I read a lot about how md5 is hacked and don’t use it for passwords blah blah blah

It is true that finding collisions in md5 is easy enough and brute forcing them with modern day computers is trivial.

But are they useless?

I Don’t Think So!

The following is based on someone getting access to your database because say you left the door open and they were able to inject some sql which revealed your user accounts. Sadly a very common occurrence.

The reasoning for not using md5’s as password hashes goes like this. I can brute force 5 Billion Hashes a second therefore I can crack all your passwords within minutes therefore md5 is terminally broken.

Well Yeah, That is correct if you don’t salt your hashes and you should! What is salting? Salting is adding random characters to the password to increase its complexity. It is done by the webserver or whatever program is using the password

It goes like this..

instead of

hash = md5(password);

you have

hash = md5(password . salt) ;// . means concatenate

Now if the cracker doesn’t have the salt he cannot brute force your password and rainbow tables and collisions are also out.  (rainbow tables are massive precomputed tables of cracked hashes)

The trouble with the above solution is two users with the same password have the same hash. That little leakage of information could be enough to crack the password.

So what you need to do is to add a unique salt, one per password. This then prevents two passwords having the same hash.

hash = md5(password  .  unique salt);

But this means you need to store your unique salt with your password. So if your database is hacked then your salts are also known! But it does give the bad hacker a headache they still need to brute force every password in your database with a different salt for each password. It makes it exponentially harder.

How about we add another salt to the system will that help? Yes it will!

If you add a third common salt to the system so that your algorithm now becomes

hash = md5(password . unique salt . common salt);

Then the bad hacker needs all three. As long as the hacker does not get the common salt then your passwords are safe. BUT DO NOT STORE THE COMMON SALT IN THE DATABASE!

If they have the database and get your common salt because you were silly enough to store it there then you are back to the salt plus unique level of complexity. Good but not great!

Remember this too, as a developer we can do all we want to protect our users passwords. But if users are stupid enough to use simple passwords and then share them across multiple sites then they deserve to get hacked.

To protect them from themselves when setting passwords for users always set a minimum complexity.

So go ahead and use md5 in the knowledge you are reasonably safe. Of course if they get access to your server then once again you are in trouble!

So the solution is two salts a unique and a common salt stored in a different media (configuration file)

AND insist on minimum complexity passwords.

md5 Is fast and that’s why its still a good choice for a busy server.

Of course you may have different reasoning so I’d love to hear it.

P.S. If you really want to give your bad hacker a hard time then add a counter to your hashing algorithm.

hash = md5(password . unique salt . common salt);
for (i = 0 to 1000000) {
           hash = md5(hash);
}