Reputation: 91805
So, I'm cool with using a per-user salt to hash my users' passwords. However, there's one piece of advice in the accepted answer:
Do not use a separate column for the salt.
This doesn't make sense to me. If I'm just catenating the hash and salt and putting them in the same column, surely that's semantically equivalent to two separate columns? In which case, that's just security-by-obscurity, no?
It's easier to use a separate column to store the salt (as long as it's per-user). Why shouldn't I?
Upvotes: 3
Views: 3082
Reputation: 2916
The security answer is that it doesn't matter.
The database answer is that the salt and the hash are different quantities, and so you should ideally store them in different columns. If you do this then the database can be said to be normalized.
However, it is not uncommon to denormalize a database to improve access speed - concatenating the hash and salt in the same column would be an example of denormalization.
One reason to keep the salt and hash separate would be that you envisage searching for one or other of them. It seems to me unlikely that this is something that you'd want to do, so go ahead and store them concatenated.
Upvotes: 1
Reputation: 4549
If you are going to store a random per user salt it doesn't really matter. Store salt+hash in one column or store salt and hash in two columns. Personally I would store it as a single column because it is unlikely you will ever be retrieving just salt or just the hash. Also if you update the salt then hash needs to be updated also and when updating the hash you might as well update the salt. Still either method of storage is equally valid from a cryptography standpoint.
I think what that comment was indicating (although poorly) is that an alternative solution is to derive the salt from another piece of per-user data, a derived salt.
As an example take username and pass it through 1000+ iterations of PBKDF2 (actually picking a unique and unusual number of iterations is better - say 2137). This would require attacker to gain access to not only the database but also your source code to defeat the system.
Now if the attacker has complete access to both password table & source code you have gained no security however if the attack has only access to the database (limited intrusion) you have stopped an attack or at least make it much more difficult.
Another aspect to consider in a derived salt implementation is if your attacker will be able to make a user account (open registration system). If anyone (including your attacker) can make an account (like say on stackoverflow) a derived salt is of less value. Why? Attacker can reverse engineer the salt and thus salt source with only access to the database via a plaintext attack (attacker knows his own password, and other details).
Upvotes: 3
Reputation: 93690
I think the second part of the first answer (the part about "dynamic salt") in that thread gives you an answer like you expect: Generate a random, per-user salt and store that with the hashed password. This is exactly what UNIX passwd (and later shadow) files have done for decades.
There's some confusion in that thread about what exactly salt is. Some replies take a very general definition along the lines of "any known text mixed into a password before performing a one-way hash". There are lots of reasons to mix known text and secret text before performing a one-way hash, and obviously the treatment of the known text in such cases would depend on the algorithm. For an example, look at http://en.wikipedia.org/wiki/CRAM-MD5 which avoids having the user send their password over the network at all by having them hash it with a "salt" specified by the server.
Upvotes: 1