I\'ve been reading up on the benefits of salting and hashing passwords, but one thing still eludes me...
When I provide a random salt for each user, how do I then know
You do not need a separate salt for every password.
The purpose of salting is to resist rainbow tables -- you convert a candidate password into a new string that has your salt in it; since the salt is some private string only you possess, knowing the hash of a salted password will not help an attacker who has a run of the mill rainbow table.
A clever attacker can try to build a custom rainbow table just for your service by creating an account, and changing his password to observe what the resulting hash is. If the salt is the same for every user, then when he sees that the hash "xyz123" corresponds to "apple", and notices that another user's hash is also "xyz123", he can conclude that that user's password is "apple". This is the point where most people decide to store a unique salt for each user.
However, this is unnecessary. You already have a unique string for each user -- the username. It's not secret, so it is not a good salt; however the concatenation of the username and a global secret salt is both secret and unique. If you store the hash of (username+salt+password), you only need to know the single global salt value at lookup time.
(it's true that this poses a greater risk if someone leaks the single global salt. But it's a technique worth considering).
when creating the hashed password you should use "double" salt
Create a salt (random md5 or sha1) then use format something like sha1("--$password--$salt--") and then store hashed password and salt in database.
Then, when authenticating you recreate the hash from --$pass--$salt-- string and compare it to the pass stored in db.
Salt is randomly generated for each user but it's saved somewhere in the database. You look up the salt for the particular user and use it to authenticate the user.
The point is, since salt is different for each user, you cannot use a prebuilt dictionary of hashes to map the hashed passwords to clear text (rainbow attack).
It doesn't defeat the purpose of the unique salt to store it. The point of a unique salt is to protect your entire users repository from attack, not a given individual user. If an attacker compromises your database and is determined enough to crack a particular user's account, they will. There's nothing we can do about this. But they would have to spend an inordinate amount of computer time doing so - enough that it would not be feasible to spend that much time on each user - thus protecting all your users. Contrast this with using the same salt for all users - once the attacker has the salt, the same tables/processes can be re-run against every user in a relatively short time.
The salt prevents someone from getting a copy of your encrypted password database and mounting an offline attack against all of the passwords at the same time. It doesn't prevent attacks against a single password.
You might enjoy reading the original Unix password security article. It does a very good job explaining what a salt is, and why we have them: http://portal.acm.org/citation.cfm?id=359172