I'm going to explain each level of security for database stored password, maybe this will help clarify the importance of salt.
Level 1: Password stored in clear in the database.
This is just pure stupidity. But sometimes, big company get their database compromised and, oh surprise, all password are stored in clear. What a shame!
Level 2: Password stored using an hashing algorithm.
This is a step toward more security. If an attacker get the hashed password, he can't still login using this credential to the service. He will first have to "unhash" the password using a Rainbow Table or by brute forcing it.
That means it require for the attacker a bit more work, but it can still be possible to retrieve the original password.
Level 3: Password stored using an hashing algorithm with a salt.
This starts to be interesting. As we saw on Level 2, an attacker that has access to the hashed password can either brute force it or use a rainbow table. Adding a salt to the original password make the rainbow table totally useless because they don't take into consideration the salt.
It still possible to get the original string using a rainbow table, but it would mean that in the rainbow table, the password+salt exists. Since a salt is generally very long, the odd having a hashed value of a string(40+) is almost impossible. The only solution left is brute force.
Level 4: Password stored using an hashing algorithm with a salt and a peper.
This is very interesting (it's the reason why I'm posting my answer since the actual ones are already interesting).
I recommend you to use an hashing algorithm like BCrypt, SCrypt or PBKDF2 since they aren't beek broken so far, and are very slow to hack, increasing the time to break one, and then a complete database of passwords.
The difference between salt and pepper is their location. The salt is generally stored in the database but the pepper is located in the code. This can seems odd but the original idea is that a database can be compromised, but not the code, leaving the attacker a salt and a list of useless hashed password. Moreover, it add even more complexity to the hashed password, making rainbow tables completely useless (if we suppose they were still a bit useful with a salt!).
In the case that only the database is compromised, even the brute force is then useless since the attacker is not looking for one value (the original password) but for two values (the original password AND the pepper).
Salt helps if the attacker wants to break many passwords
.Ok so far.Then:wants to break into an account on that site, any account
.If that's the purpose, since the salt is cleartext and unprotected, why can't he achieve exactly his purpose?I.ebreak into an account on that site, any account
.One account/password would be enough – Jim Apr 21 '12 at 20:43hash("password")
against every account. If every account has salt, the attacker needs to checkhash(salt1+"password")
against account1, thenhash(salt2+"password")
against account2, and so on. – Gilles 'SO- stop being evil' Apr 21 '12 at 20:51PBKDF
, you mean to usePBKD
first on password and then hash the resulting key? – Jim Apr 21 '12 at 21:28hash(hash(hash(…(hash(password)))))
. Just repeating the hash wouldn't be so good, though, so PBKDF2 and other similar functions throw kinks in the works at each iteration, to make sure that no precomputation can help the attacker. I recommend reading Thomas's answer (and before that the definitions of PBKDF2 and Bcrypt on Wikipedia). – Gilles 'SO- stop being evil' Apr 21 '12 at 21:50