Should a salt be stored in the same database as the hash?


To protect against dictionary and rainbow table attacks it is well known that passwords should be salted before hashing. The salt (unique to each password) gets stored with the hash, often in the same string separated by a semi-colon.

However if the salts and hashes are stored together and the database is compromised then the attacker will have access to each salt used for each hash, which defeats the purpose of the salt.

Is this a legitimate concern? Should salts be stored in a separate database to hashes?

Why should this post be closed?

1 comment

3 answers


The purpose of a cryptographic salt is to make the same input (password) hash to different values in different instances, yet retain the hash function's deterministic properties. Salting accomplishes that by concatenating a random value with the password itself before hashing, and storing the value of the salt somewhere alongside the salt+password hash.

This, in turn, renders generating and storing lists of precomputed hashes impractical, because each candidate inputs list will need to be hashed separately for each salt value. If the salt value is large enough, this causes the work and storage requirements to become prohibitive, even for relatively small lists of candidate input values (passwords). This forces the attacker to compute each hash separately for the particular salt; they can't precompute hashes and then reduce finding the password to little more than a table lookup or a search.

Since the salt is chosen at random, there is a very good chance that every single user account (and every time each user changes their password) has a different salt. A large enough salt can virtually guarantee global uniqueness simply by being picked at random.

At the same time, any process that needs to verify that a given candidate input matches the hash, will by necessity require access to the salt value for the particular hash anyway.

The idea behind this is that it forces the attacker to basically do the same work as the legitimate software for each candidate user account and password combination. In the case of a legitimate user authenticating to a legitimate system, making computing the password hash take 10 or 20 or even 100 ms is largely inconsequential, and storing precomputed values is of no benefit; but making an attacker do that work for each combination of user account and candidate password greatly increases the attacker's workload compared to being able to do the work just once for each candidate password.

The fact that the salt is stored together with the hashed password does not materially change that.

Therefore, because of what a salt is intended to do and how it does that, as long as the salt is meaningfully large and selected at random, storing the salt together with the password hash should not materially decrease system security compared to storing the salt separately. As already discussed, it also likely makes it much easier to keep the two values in sync both when reading and when writing, both of which are critical to enable successful authentication by legitimate users.



When I first learned about salting, I thought the same thing. But as I understand it, because each salt is unique (or substantially unique within a given database table), storing the salt & hash together does not open you up to a rainbow attack. On the other hand, if they are stored separately (separate database; separate fields in a table or even separate tables in a database would in the end be little different from all in one field), you now need to do multiple retrievals to verify the data (one to get the salt to create the hash, the other to verify the hash), which slows down access, raises serious synchronization issues, and may even increase possible security vulnerabilities.



The issue with using two separate databases is you need to:

  • store both access strings
  • back up both databases
  • manage both databases
  • keep both databases patched

By the time you have done that, the risk of both databases getting hacked is much the same as the risk of a single database getting hacked.


Sign up to answer this question »