views:

983

answers:

3

I've always used a proper per-entry salt string when hashing passwords for database storage. For my needs, storing the salt in the DB next to the hashed password has always worked fine.

However, some people recommend that the salt be stored separately from the database. Their argument is that if the database is compromised, an attacker can still build a rainbow table taking a particular salt string into account in order to crack one account at a time. If this account has admin privileges, then he may not even need to crack any others.

From a security perspective, is it worth it to store salts in a different place? Consider a web application with the server code and DB on the same machine. If the salts are stored in a flat file on that machine, chances are that if the database is compromised, the salts file will be, too.

Are there any recommended solutions to this?

+17  A: 

The point of rainbow tables is that they're created in advance and distributed en masse to save calculation time for others - it takes just as long to generate rainbow tables on the fly as it would to just crack the password+salt combination directly (since effectively what's being done when generating rainbow tables is pre-running the calculations for brute-forcing the hash), thus the argument that by knowing the salt someone could "generate a rainbow table" is spurious.

There's no real point in storing salts in a separate file as long as they're on a per-user basis - the point of the salt is simply to make it so that one rainbow table can't break every password in the DB.

Amber
Agreed. The threat model you're protecting against by storing the salt separately is a user who can somehow access the salt in the DB through nefarious means, but not the hash (in the DB). And that that person will start computing a rainbow table in advance, assuming he will be able to find the hash later. Not impossible, but also not worth the engineering effort for defending aginst this single attack avenue.
Tom Ritter
+2  A: 

Often, they are prepended to the hash and stored in the same field.

There is no need to store them separately - the point is to use a random salt for each password so that a single rainbow table can't be used against your entire set of password hashes. With random salts, an attacker must brute-force each hash separately (or compute a rainbow table for all possible salts - vastly more work).

If you had a more secure storage location, it would make sense to just store the hashes there.

Andrew Medico
A: 

If it's per entry then it's a nonce

David Plumpton
It is a nonce (number-used-once) if the salt is used every time the password is checked against the hash?
geofftnz
No, because while it's per-entry, the entry may be referenced multiple times, with the same salt being used for each access (the word "entry" here refers to entry in a database table, not entry as in access).
Amber
You could call it a nonce, but it's still a salt. "Salt" applies specifically to password hashing - and should _always_ be per-entry.
Nick Johnson