The salt has two main purposes as I understand it.
(1) To ensure that two users who choose the same password, get different password hashes.
Say the CEO, and the janitor, choose the same password. Without a salt, they'd both get the same hash. This means that an attacker who managed to download the password file, could instantly see that the CEO, and the janitor, have the same password (whatever that is). So instead of putting a keylogger on the CEOs laptop, he'd just beat the password out of the janitor! Or if the janitor was the attacker, he'd instantly see that his own password, was also the CEO's - so he could log in as the CEO, without having to try multiple passwords and risk a system alert.
With a salt, the two hashes are completely different, and no attacker can possibly know that several users have the same password. Salting the passwords also ensures that users who choose the same password on different systems, get different hashes on each of those systems.
For (1), the only actual requirement, as far as I can see, is that the salt is different for different users - because even the slightest change in salt+password, will cause an enormous change in the hash thereof. So you could just use an increasing number 1, 2, 3 etc. It needn't be large, random, or secret - just different for different users.
However, in practice, when you're storing the password for a new user, you don't necessarily want to scan the other users' salts, to check you pick a different value; and you sure don't know what salts were used on other systems! So a common approach is to "take a chance", and just pick a big random number, hoping that the resultant number hasn't been picked before. The bigger the number, the less chance it has been picked before.
(2) To reduce the chance of password cracking using rainbow tables.
Say an attacker pre-computes the hashes of a million common passwords, and stores those in a table. So the table has a million (password, hash) entries. (These are commonly called rainbow tables.) Then, when he downloads a password file, he just looks-up each of the hashes, from that file, in that table. If hash value 1234567890 matches table entry ("letmein", 1234567890), he now knows that password "letmein" will produce that hash - voila! The table takes time to generate, and space to store. But once done, it will instantly crack those million passwords - if they are unsalted.
But say each password is salted with one of (say) 1000 different values - perhaps just a number from 1 to 1000. Now the attacker has to pre-compute each password 1000 times - once for each possible salt. So the table is now a thousand times larger. Clearly, if the salt is large enough, this makes the table infeasible - it takes too long to generate, and is too large to store.
For (2), the requirement is, as I understand it, that the salt has many different potential values, and is unpredictable. If the salt doesn't have many different potential values, the table is still feasible. And if the salt is predictable, the attacker just generate a rainbow table for the predictable values, and hopes for the best!
So to meet both (1) and (2), you just pick a large random number for the salt. As I understand it, 32 BYTE salts are coinsidered the go these days.
Using the DATE as a salt is a very very bad idea. That wouldn't even achieve benefit (1) - let alone benefit (2). If I saw code that used the date for a salt, I'd not trust that code for any security related functions of any description - the author has no idea what he's doing.
This is my understanding of salts (in regard to password hashing). I guess I'll soon find out if I'm right or not :-)
TC
bcryptor preferablyscryptinstead. – Mikko Rantalainen Apr 19 at 10:27