My understanding is that a salt is not intended to be secret, it is merely intended to be different from any centralized standard so that you can't develop a rainbow table or similar attack to break all hashes that use the algorithm, since the salt breaks the rainbow table. My understanding here might not be completely correct, so correct me if I'm wrong.
In a widely-used piece of open-source software, the salt would be widely known, and this opens you up to attacks because now they can simply attack the salted version of your hash and create rainbow tables that include the salt data.
As I see it, there are two options to deal with this. The first is to change the salt with every new version of the software, but this is no good because new versions of the software would no longer be able to test against old password hashes.
The second solution I thought of was to have a salt per password stored; in other words, each password gets a different salt. The downside is that the salts have to be associated with the password hashes in some way, probably just by sticking them right next to the password in the database. It might be even okay to use the username (it might not, though, probably usernames are too short).
My question is, is this acceptable? Is there any extra risk associated with storing the salt directly with the password it hashes? It seems to me that storing the salt in the source code is no different, so there's no security loss by storing the salt with the password.
DISCLAIMER: I'm not using this for any real life security system. In fact, I have never designed a password system of any kind. I'm just keeping myself vaguely educated about security issues.
Since the whole purpose of a salt is to prevent password attacks with precomputed tables (e.g. rainbow tables), storing the salt along with the hashed password is actually harmless.
A cryptographic salt is made up of random bits added to each password instance before its hashing. Salts create unique passwords even in the instance of two users choosing the same passwords. Salts help us mitigate hash table attacks by forcing attackers to re-compute them using the salts for each user.
Salt should be stored in an airtight container in a cool, dry, dark location. Salt can be purchased in bulk and repackaged for long term storage in smaller containers. Oxygen absorbers are not recommended when packaging salt for long term storage.
Hiding a salt is unnecessary. A different salt should be used for every hash. In practice, this is easy to achieve by getting 8 or more bytes from cryptographic quality random number generator.
update: use a competent library e.g. passlib for Python.
These take care of generating a per-password salt and they use a proper hashing algorithm (its not enough to just use a cryptographic hash such as SHA1; you have to apply it in a way that makes it very slow to reverse e.g. looping 1000 or more times over it etc. This is how password hash functions like bcrypt work. Password storing libraries do all this properly; they typically produce a string that is delimited so they can determine the hash system and work factor used; you just store the string without needing to know this.
You can store the salt in 'plain-text' in the table.
The salt does not need to be secret to be effective
it just needs to be random.
The salt strengthens a password by making the hashed value incomparable to the same password in the same or other database, and invalidating large pre-generated lists of common password to hash lookups (e.g. 'rainbow tables').
So it's critical that the salt is unique per user and is some random value stored with the password; the alternatives outlined in the question (using the username as the salt, using a single salt value for the whole application) each fail:
if systems use the user-name or other trivia, then the password can be compared to other users with the same name in other systems (imagine how often the 'administrator' or 'root' user account uses the same password in different systems...)
if the system uses a single random salt for all users in the same system, then two users who by chance have the same password would have the same hash, and guessing one user's password would trivially compromise the other.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With