Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I don't like this idea. But I can not come up with a technical argument against it. Can somebody explain it to me? The basic idea is:

$passwd = 'foo';
$salt = hash($passwd);
$finalHash = hash($passwd . $salt);

The $finalHash is what would be stored in the database. I do understand that two users with the same password "foo" would have identical hashes. But that is only one weakness of this plan. And such collisions, while dangerous, are not the primary reason we use salts with hashes. But so far this the only technical objection I have come up with to argue against this.

My understanding is that salts should be random and should be unique for each use of the hash. And this scheme appears to violate both requirements. But I can't figure out how an attacker could benefit from this seemingly flawed use of salted hashing.

share|improve this question
    
Really, just use bcrypt. There is a version for whatever language you're using. –  Stephen Touset Apr 1 '13 at 1:14
5  
"And such collisions, while dangerous, are not the primary reason we use salts with hashes." Actually, yes they are. –  Ilmari Karonen Apr 1 '13 at 9:41
    
Actually, even i do not understand that why this is bad. As i saw few of other answers they say that if someone breaks into your database then they can easily break the hashes but what i think is that even if we use random salt each time then we have to store them with our hashed password for comparison and if someone breaks into the database then he will also get the salt used for hashing. In that case also the attacker can break the hashes as he knows the salt used for each password. –  Chirayu Chiripal Apr 1 '13 at 14:52
    
@ChirayuChiripal: You are correct that if the attacker has the salt and the hash then they can try to determine the password that produced that salted hash. That's not the point. The point of the random salt is so that the attacker cannot start the attack on the hash before they obtain the database. If the password hashes are not salted randomly then the attacker can spend hours, days, weeks, years, computing the unsalted hashes of billions of possible passwords, in preparation for the day that they manage to get the database. That day they would then have no work to do. –  Eric Lippert Apr 1 '13 at 17:02
5  
@EricLippert The point of the random salt is actually so that the attacker cannot use the results of an attempt on one password to gain information about all passwords. With the approach in the question, an attacker only has to hash pass123 once to learn if any users have that password. With unique salts, they would have to hash pass123 for every user before being able to move to the next guess. As a counterpoint, a constant site-wide salt stored in the database thwarts your concerns with precomputation, but does nothing to prevent what I've described. –  Stephen Touset Apr 1 '13 at 18:26
add comment

4 Answers

up vote 11 down vote accepted

If two users have the same password, then the salt will be the same, resulting in the same hash for both. This is undesirable, because it leaks information about passwords. If Alice breaks into your database and sees that Bob has the same hash as her, she can use that information. Pick something that is guaranteed to be unique.

Your biggest problem here, though, is that you're using hash without any information about what that hash is. Depending on the system, it might even be the old crappy 3DES implementation that strips everything after the 8th character. You should be using a proper KDF such as bcrypt or PBKDF2.

share|improve this answer
    
In the psuedocode I wrote, hash() represents any hashing algorithm. But I do plan to require some modern algorithm when we finally implement this. –  joe user Mar 31 '13 at 20:48
2  
If it was 3DES is would be dropping everything after the 24th character, which would be better; but, alas, the traditional Unix "crypt()" password hashing function is based on a modified DES, not 3DES.\ –  Thomas Pornin Mar 31 '13 at 20:59
    
@ThomasPornin My bad, that's correct. –  Polynomial Mar 31 '13 at 21:03
add comment

To answer this, one has to understand why salts are needed in the first place. This is explained pretty well in How to securely hash passwords?; here's an excerpt from the accepted answer:


Salts: among the advantages of the attacker over the defender, is parallelism. The attacker usually grabs a whole list of hashed passwords, and is interested in breaking as many of them as possible. He may try to attack several in parallels. For instance, the attacker may consider one potential password, hash it, and then compare the value with 100 hashed passwords; this means that the attacker shares the cost of hashing over several attacked passwords. A similar optimisation is precomputed tables, including rainbow tables; this is still parallelism, with a space-time change of coordinates.

The common characteristic of all attacks which use parallelism is that they work over several passwords which were processed with the exact same hash function. Salting is about using not one hash function, but a lot of distinct hash functions; ideally, each instance of password hashing should use its own hash function. A salt is a way to select a specific hash function among a big family of hash functions. Properly applied salts will completely thwart parallel attacks (including rainbow tables).


So the problem of your salt is that it doesn't interfere with parallelizing breaking the hashes, which is the very purpose of salting. I strongly recommend you to read the original answer, it has further advice on salting.

share|improve this answer
1  
Based on reading that, I do see that the problem with my example is that the salt is not guaranteed to be unique. But I still don't understand how an attacker could exploit this lack of randomness (besides the collision of two users with the same password). –  joe user Mar 31 '13 at 20:51
    
@joeuser Let's say you have a database with N hashed passwords that gets stolen. Using your scheme, each guess the attacker makes has to be hashed twice, then it can be compared against all N (which is usually trivial compared to the cost of hashing). With unique salts, the attacker would have to perform N hash operations to see if the guess is correct for anything. The attacker also wouldn't realistically be able to pre-compute any hashes as part of a rainbow table attack (assuming a reasonable sized hash), while yours does nothing to thwart a rainbow table attack. –  Kitsune Mar 31 '13 at 21:19
9  
To simplify @Kitsune's example, assume I'm brute-forcing my way through your password database. If I compute the hash for pass123, I know immediately if any of your users have that password, even if it's only one of them. On the other hand, if you were using unique salts, I would have to hash pass123 for every one of your users. –  Stephen Touset Apr 1 '13 at 2:53
add comment

If you use the password as "salt" then you are not using any salt at all; you are just hashing the password.

If two users choose the same password, they end up with the same hashed password. That's what is often told as if it explained the problem, but it seems that most people get it wrong. They imagine that this means "collision", which, for some reason, is considered by many to be a bad word when talking about password hashing. But that's wrong, and not the point.

The point is determinism. Suppose that I, wantonly, grab a copy of the hashed passwords for 1000 users (e.g. I retrieved an old backup tape from your garbage bin). Then I can "try" potential passwords: I hash a potential password (using the password itself as "salt") and then I look up the value among the 1000 hashed values. This means that by paying the computational price of one hashing, I actually try one thousand user+password pairs. I am attacking one thousand of hashed passwords in parallel, for the same cost as attacking a single one. This kind of parallelism can express itself under several guises, including rainbow tables.

We really prefer it when attacking 1000 hashed passwords costs 1000 times the cost of attacking 1 hashed password. To do that, you need real salts, i.e. salts which are distinct for distinct users, even when they happen to use the same password -- and, actually, when they potentially use the same password. When there is no real salt, the parallel attack works not because some users do choose the same password, but because if they had chosen the same password then they would have obtained the same hashed value. They don't actually need to choose the same password to trigger the weakness.

Using the user name as salt is much better. It is not good, mind you; but still better. What is even better, to the point of being actually decently secure, is to use random salts.

share|improve this answer
add comment

Using a username or password as a salt doesn't sound like a good idea to me.

An attacker might reasonably guess that you're using the username or password as the salt. Depending on your setup it might be very reasonable to assume an attacker could gain access to usernames.

Also depending on how strict your system is at enforcing passwords the attacker could take advantage of passwords that appear in a dictionary of known/common passwords, and as these are used as the salt your system would be vulnerable to this kind of attack.

Using a salt that doesn't rely on user input is a much better idea.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.