Comment by danbruc

14 years ago

»What hashing scheme do you use?« does not matter for most users.

Most users use weak passwords and a substantial part of this passwords is easy to recover using a dictionary attack. It does not really matter if you use MD5, SHA1, SHA2, HMAC, PBKDF2, bcrypt, scrypt or whatever, nor does it matter if you use no salt, the same salt for all users or a unique salt per user. Even for PBKDF2, bcrypt and scypt the cost factor will - for practical reasons - usually not be large enough to mitigate dictionary attacks using a few thousand of the most common passwords. Therefore weak passwords are compromised regardless of the used hashing scheme. And because especially users with weak passwords tend to reuse the password for different accounts many other accounts are compromised, too.

A user caring about security will not reuse passwords for different accounts and this alone reduces the impact of the event by a huge amount. Further a strong password alone makes it very unlikely that attackers will recover the password even if only unsalted MD5 is used for hashing. Therefore - unless the password is stored in plain text - it is highly unlikely that an attacker will be able to access an account protected by a strong password.

I definitely don't want to argue that using unsalted MD5 is okay - it is not - but for the average user the difference between a weak and a strong hashing scheme is not as large as one would naively expect. Strong hashing schemes will especially protect users using infrequent dictionary words or medium length hard passwords because the additional computation power required to perform a dictionary or brute force attack will force the attackers to use smaller dictionaries and shorter passwords.

Finally storing passwords may benefit from security through obscurity. If the attacker is unable to figure out the used hashing scheme he will be unable to perform a dictionary or brute force attack. This does not mean everyone should come up with there own hashing scheme - this would do MUCH more harm than good - but, for example, using a unknown random - 294,897 instead of 300,000 - cost factor and keeping it secret or adding a second secret salt buried deep in the code to the salt stored together with the username and hash will make it quite a bit harder for the attacker to perform an attack unless they got the information from an insider or were able to steal your code or binaries.

Using an in-code secret key (as opposed to the not-secret-by-necessity salt) is commonly referred to as a pepper. It improves security in the cases when an attacker has access to your database but not to your code or filesystem.

Figuring out the hashing scheme used for a given hash is frequently trivial. All an attacker needs to do is hijack his own hashed password and salt and then run combinations of common hashes with salting patterns until he gets a hit. This is going to be hundreds of combinations to test on the high end, and will generally yield results very easily.

> It does not really matter if you use ... a unique salt per user.

I agree with the other points that you make on this aspect but I do not quite understand this particular point (quoted above) can be true. If you use a strong unique salt for each user's password, then you are padding the length of actual password hashed and thereby effectively reducing the possibility of a successful dictionary attack to virtually zero. If this is so, then how could one mount a successful dictionary attack ?

  • It is common to store per user salts together with the hashes, often even as a single string formed by concatenating the salt and the hash. Therefore getting hold of the hashes usually means getting hold of the slats, too.

    But the other case I mentioned - using the same salt buried deep in your code for all users (what is called a pepper as I learned recently) - will do what you describe until the attacker is able to figure out the pepper used by either stealing the code or brute forcing it.

    Finally note that just using a pepper is no good idea and even when combined with a salt needs some careful thoughts. Just using a pepper will yield equal hashes for equal passwords while using a unique per user salt will avoided this. The other problem is that with a pepper you are reusing the same secret for each user. Therefore an attacker has thousands or even millions of samples and may be able to extract information if the scheme is not designed carefully. Combining password, salt and pepper must essentially avoid the same pitfalls as keyed hash functions when combining the key and the message. See for example the design principles behind HMAC [1].

    [1] http://en.wikipedia.org/wiki/Hash-based_message_authenticati...