How do I implement salt into my login for passwords?

Timmay picture Timmay · Feb 3, 2010 · Viewed 12.1k times · Source

I want to implement a salt into my login system but am a bit confused on how this is supposed to work. I can't understand the logic behind it. I understand md5 is a one-way algorithm and all of the functions that I have come across seem to hash everything together. If this is the case, how does one get the password back out for comparison? My biggest question is, how is salting a users' password safer than just hashing the password? If a database was ever to be compromised, the hash along with the salt is in the database. Isn't this all that a hacker would need?

I also found another post here on SO where another developer said :

"Ensure your salt and algorithm are stored separately from the database"

I would like to store the salt in the database. Is this really a problem if I do?

I'm looking for some help on understanding how this works and also what the best practice might be. Any help is greatly appreciated.


EDIT: I want to thank everyone for their responses and ideas. Even though I may be more confused now, it has certainly been a learning experience for me. Thanks again guys.

Answer

Michael Borgwardt picture Michael Borgwardt · Feb 3, 2010

The point of a salt is to prevent attackers from amortizing the cost of a brute force attack across sites (or better yet, when using a different salt for each user: all users of a site) through precomputed rainbow tables.

With plain hashing, an attacker can compute such a table once (a very long, costly operation) and then use it to quickly find passwords for any site. When a site uses one fixed salt, the attacker has to compute a new table specifically for that site. When a site uses a different salt for each user, the attacker can stop bothering with rainbow tables - he'll have to brute-force each single password separately.

Storing the salts separately is not necessary to gain this advantage. In theory it would be even more secure because it would neutralize the weakness of dictionary or short passwords. In practice, it's not worth bothering with because at the end of the day, you need access to the salts somewhere to check passwords. Also, trying to separate them would lead to more complex systems - and the more complex a system is, the more opportunities for security holes there are.

Edit: My concrete recommendations:

  • Generate long pseudorandom salt for each user and store in in the DB
  • Use a bcrypt-based hash
  • ideally, don't implement it yourself, use an existing library instead