Password hashing with sha256
Securing your users passwords is essential if you run a web site that require users to log in, but this is often neglected, leaving many web sites with user profiles stored with plain text passwords. Here why you should start storing hashes instead of passwords, and how to do it.
So, what is hash anyway?
A hash is a one-way mathematical process that can be thought of as a fingerprint of a piece of data. It's easy to generate a hash for any string, but next to impossible to recover the data from the hash itself. This makes it ideal for storing user passwords. In fact, since you're not storing the password but merely a digital fingerprint of it, you will not be able to read or extract the password from the database. Permalink for this article http://mirror.magicode.org/content/Password_hash_and_salt_with_sha256
Why not just store the password in plain text?
Why not? It's easier, right? Well... statistics has shown that users often use the same password for many different web sites. If one is compromised, the hacker can try other web sites for the same username and password, and there's a good chance he'll be able to get into the user's account on those other sites as well. This is bad for the user, but it's especially bad for you, since you're the one who provided the hacker with the password, never mind that the user should not use the same password twice on different sites. It reeks of bad publicity, and there's really no excuse for storing the passwords in plain text. In most cases, you really don't need to store the passwords. This text was originally written for http://blog.magicode.org
Generating a hash
A typical hash can be generated like this: If you see this notice on any site other than magicode.org, it's probably been lifted without consent
<?php
$password="U!?$%&LS&a&m&C";
$hash=hash("sha256",$password);
echo $hash;
?>
This will output:
b41108475b65c77e8580d99400137e7eebc7f7ecd27cee639ddceeda8632e2b7
If the user now wants to log in and he sends the password U!?$%&LS&a&m&C, all we have to do is get the hash from the database and compare this with a hash of the submitted password. If they match, the password checks out, and we never have to store the password itself in the database. It's a win for the user, since his password cannot be stolen, and a win for the service provider, since he don't have to worry about compromising his users passwords in case the data gets stolen.
Salting your hashes
One thing to note about the above method is that if two different users both use the same password, their hashes will be identical. If a hacker gets access to a list of 100.000 passwords, and 5.000 of those passwords share the same hash, it's a good chance he'll single out that hash and work on hacking it.
This is where salting comes into the picture. When you generate the hash, it's a good idea to provide a salt. A salt is like a second password that you apply to the original password before you hash it. If you use a random salt every time you generate a hash, you can have 5000 users hashing the same password, and still end up with 5000 unique hashes.
If we take the above example and add a salt to it, we get the following:
<?php
$password="U!?$%&LS&a&m&C";
$salt=uniqid(rand(), true);
$hash=hash("sha256",$password.$salt);
echo $hash;
?>
This will output something like this:
2e64af37354fe6b282f734dd436bae37cc29d82f73deb679178702deba5ca746
Actually, it will output a different hash every time you generate the hash, since the salt changes the password string. I'm using the standard php function uniqid to generate the salt, but it can be generated in any number of ways. The importing thing is to store the salt with the hash, so that you have a way to check the password against the salt when the user tries to log in again.
Algorithms
In this article, I've used sha256 as my base example. It's a strong algorithm that has not been cracked (so far). I have prepared a class for php5 that will let you generate a salted sha256-hash without any fuzz, and a method for checking a submitted password against the stored hash and salt.
class.secureHash.php.zip (6.09Kb)
Summary
Hopefully, this article made you realize the advantage of storing hashes instead of plain text passwords in your database. It's safer for you, and it's better for your users, and with the above class, there's really no excuse for sticking with plain text. If you do end up using the class, I'd appreciate a link back to this blog, but there are no strings attached.
