Salts, how does the script know what the salt is? I am new to PHP programming and trying to grasp the idea of hashing and encryption for protecting passwords, credit card details and such. I've done a lot of reading about MD5 which I think I understand the basics of now. I've seen places recommending that I use SHA2, which I don't understand how to implement. 

Back to my question. I can understand how a script can tell if a password is correct or not by hashing the password and comparing the value against the hashed one in the database. My problem occurs when trying to understand salts. If I have a dynamic salt such as the date (yes, I have heard its a bad one to use), how does the script know that a password is correct because the salt will be different for the entered password and the one stored in the database.

For example:
Say the original password was created on the 21/02/2011:


unhashed with salt:

mypassword210211

hashed with salt:

cbc0a790b2f28fc72ca43eb749028b9f



Then if I check my password today:


unhashed with salt:

mypassword30012012

hashed with salt:

e4af7ca7e263750a15be642d903c9ac9



They're completely different, so how does the script know that they are the same? Do I have to store the salt used on the specified password in the database so it knows what to use next time?

I'm rather confused and its highly likely that I am not understanding the whole hashing process properly. I've done my research, but whether I have done correctly or not I don't know.
The salt has two main purposes as I understand it.


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.
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.