views:

378

answers:

5

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 what the salt was when I try to authenticate them to login?

so if I do..

HASHPW = PW.RANDOMNUMBER

I could store the random number in the database, but that seems to kill the entire point of adding the salt.. doesn't it? I could also use a non random number for each salt, but then that also kills the point of the salt because if they figure it out they have all my users passwords...

I just started learning PHP and MySQL and abstract things like this have been confusing me

Thanks!

+10  A: 

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

Mehrdad Afshari
So then the attacker obtains both the salt and the hash using sql injection and then breaks it with John The Ripper.
Rook
@The Rook: It's probably won't protect from figuring the password out for a single person if you have access to salt and hash. It will, however, prevent the attacker from matching a single rainbow table with your whole database and figure out plenty of passwords in one go.
Mehrdad Afshari
@Mehrdad Afshar correct, but all you need is the administrator's password.
Rook
@The Rook: If all you care about is the website you took over, yes. But I don't think you need a password if you have access to such a database directly. The much bigger issue is leaking your users' private passwords. Then again, we all use a unique password for every single website. Don't we? ;)
Mehrdad Afshari
+6  A: 

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.

Rex M
A: 

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.

Eimantas
+1  A: 

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

SquareCog
unnecessary - correct, sorta defeats the entire idea behind MD to do something that results in another secret, but if we have typical user and append 074BBF6C-ABAF-11DE-8DEE-414956D89593 and .doHash() with this as a salt doesn't typical user password patterns defeat the effort? If the salt is protected, it can be forgotten. ( I hope no newbies stay up at night worried about this )
Nicholas Jordan
+1  A: 

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

vy32