Can per-user randomized salts be replaced with iterative hashing?
- by Chas Emerick
In the process of building what I'd like to hope is a properly-architected authentication mechanism, I've come across a lot of materials that specify that:
user passwords must be salted
the salt used should be sufficiently random and generated per-user
...therefore, the salt must be stored with the user record in order to support verification of the user password
I wholeheartedly agree with the first and second points, but it seems like there's an easy workaround for the latter. Instead of doing the equivalent of (pseudocode here):
salt = random();
hashedPassword = hash(salt . password);
storeUserRecord(username, hashedPassword, salt);
Why not use the hash of the username as the salt? This yields a domain of salts that is well-distributed, (roughly) random, and each individual salt is as complex as your salt function provides for. Even better, you don't have to store the salt in the database -- just regenerate it at authentication-time. More pseudocode:
salt = hash(username);
hashedPassword = hash(salt . password);
storeUserRecord(username, hashedPassword);
(Of course, hash in the examples above should be something reasonable, like SHA-512, or some other strong hash.)
This seems reasonable to me given what (little) I know of crypto, but the fact that it's a simplification over widely-recommended practice makes me wonder whether there's some obvious reason I've gone astray that I'm not aware of.