2007-11-04
Thinking through salts for passwords
No one who's sane stores actual plaintext passwords; instead they hash the password in some way and store the result, throwing away the password itself as fast as possible. There are three ways you can do this:
- you can hash just the password.
- you can hash some global value plus the password.
- you can hash some per-user value (a 'salt') plus the password.
If you hash just the password, anyone who can somehow gain access to your password hashes can immediately run them through a precomputed dictionary of hashes to see what pops out.
If you hash a global value plus the password, the attacker can no longer use their general precomputed dictionary. However, they can still compute a special dictionary just for you and check all of your hashes against it, either by precomputing the dictionary or by just checking every one of your hashes against every hash they generate.
If you use a per-user value, an attacker cannot compute a site-wide dictionary for your hashes; they must attack each password one by one. This is obviously the best option.
(I don't know enough to know if adding a global value too does any good. I think that at the most it insures that the same password plus salt on two sites will have different hashes. However, a good salt should be large enough and random enough that this is relatively rare anyways.)
Note that all of this says nothing about the difficulty of attacking a single password. As Matasano Chargen reminds us, that comes down to the speed of your password hashing scheme, and things like MD5 and SHA1 are embarrassingly and dangerously fast and should be avoided if you have a choice.
(This is partly me thinking this through out loud to fix it in my head.)