Many websites will email your password to you if you have forgotten it. When I create a new account on a website, I don’t want them to know my password! They shouldn’t be storing my password somewhere as plain text. Granted, the site could be storing a hashed version, and simply using an algorithm to unhash it, and send you back the unhashed version, but I don’t like this either. I don’t want them to even be able to unhash my password!
No hashing algorithm is completely unbreakable. Hashing algorithms such as MD5 or SHA-1 have been shown to be breakable (MD5 much more easily than SHA-1), but storing the MD5 hash of a password is still SIGNIFICANTLY more secure than storing the plain text, or an easily crackable custom hashing algorithm. Cracking an MD5 sum can take a few minutes, several hours, or even days, depending on the CPU power available, SHA-1 even longer.
We can create an even more secure hash by combining the efforts of a custom hashing algorithm and MD5 to create a unique custom hashing mechanism. This is an example of how you should store your users’ passwords. We want to “salt” the original string, and then hash the salted version, and store only the hash. When it comes time to authenticate a user’s login attempt, we run their input through the hashing function. If the two hashes match, they’ve inserted the correct password.
Here is an example of such a custom salted hash:
Our string to be hashed is “password.” First, let’s come up with a salting mechanism. For this example, we’ll use something simple. The salt used has to be retrievable and positively recreatable. “Password” has 8 characters. Lets take (in PHP)
$salt = floor(strlen("password") / 2);
That is the length of the string, divided by two, rounded down to the nearest whole number. In our case the answer is 4. floor() does nothing for us here, but if the string length is odd we want a whole number, and we want the same whole number every time a string of that length is used.
Now we have our salt, 4. Let’s hash up the 4.
$salt_sum = md5( decbin($salt) );
I took 4, converted it to binary (results in 100), and found the MD5 sum of that as a string, the result is: f899139df5e1059396431415e770c6dd
Lets prepend that to our input string, “password” and find the MD5 sum:
$hash = md5($salt_sum . "password");
Now, our result is: c88e94b4d0f8e1c303f3b79d131a2d13 — and THAT is what we want to store. Now we can recreate that, and now our MD5 sum is incredibly difficult to break, with the pre-hashed value containing a 32 character “random” string, plus the original 8.


[...] Sean Jordan web developer « Don’t store passwords as plain text! [...]