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.

Ever since I've been making sites that require a user to log in with a username and password I've always kept the passwords somewhat secure by storing them in my database hashed with a salt phrase. Well just recently I read it is bad practice to use a single static salt word. Instead you should use a random salt for each user.

I under stand generating a random salt word for each user. But my question is, if you have to store the random salt also in your database so you can use it to cross reference it later to check the users inputted password when they log in. Doesn't that make it just as easy if usernames and passwords are stolen from your database then wouldn't they have just as much access to the random salt values as well? Seems like that extra layer of security doesn't really add much to the equation.

Or am I going about this all wrong?

share|improve this question
6  
The reason I down-voted the answer with "they wouldnt know the method of encryption" (now deleted, so I can't comment) is Kerckhoffs's principle. The enemy knows the system. Don't assume any of the system (which hash algorithm, iteration count, etc.) is secret. Only the actual password is a secret. –  Matthew Flaschen Jun 20 '12 at 21:59
    
I think this is a great question. I've learned a great amount of knowledge from the answers of this question, especially @Matthew Flaschen's answer. I think you should undo your flag. –  RPM Jun 20 '12 at 22:05
3  
@ColeJohnson Its not about a specific piece of code but its still about programming security –  Ryan Jun 20 '12 at 22:09
    
@RPM I did say it was a great one, but should be somewhere else. –  Cole Johnson Jun 20 '12 at 22:10
    
I thought I read this comment earlier but it must have been deleted because I don't see it now. But I guess if my entire database is compromised then it wouldn't matter so much because potentially all the rest of the users information is now accessible anyways and the password wouldn't matter except for keeping it secret from the public in case of it being used multiple times on other sites. –  Ryan Jun 20 '12 at 22:15
show 2 more comments

migrated from stackoverflow.com Jun 21 '12 at 14:10

This question came from our site for professional and enthusiast programmers.

5 Answers

It does add one significant thing. If they steal the database, they have the username, per-user random salt, and hashed password. But they still don't have the original password. To reverse the hash, they will generally have to do a significant amount of separate work for each user.

Without any salt (a very bad idea, as LinkedIn learned), attackers can use pre-existing rainbow tables and have no per-user work for hashes that benefit from the tables. Even if no part of the hash is in the table, they can pool work (e.g. if a user has two accounts with the same obscure password).

With a per-site salt, they can generate a rainbow table for the site, and still share work between users.

Remember that if they do crack a user's password, besides being able to log in to your site, they can probably also log in to other sites the user uses.

share|improve this answer
    
One-way functions are pretty good with salt. Especially if the hackers don't know what function you used. –  TheZ Jun 20 '12 at 21:56
4  
@TheZ, like I said above, you should assume the attacker knows the function. Kerckhoffs's principle. –  Matthew Flaschen Jun 20 '12 at 22:00
4  
TheZ: It's usually fairly easy to tell what function was used based on the length. The function should never be considered a part of your security, as keeping that a secret only equates to a security through obscurity measure. I would assume if the DB server is compromised, it's possible the app server can be compromised, at which point your app can be decompiled and the function becomes obvious. –  hsanders Jun 20 '12 at 22:01
    
I said 'especially', not 'given'. –  TheZ Jun 20 '12 at 22:02
2  
@Ryan it does not matter, salts are not supposed to be secret, if helps if they are, but the what they are supposed to be used for is not allowing precomputed tables or re-using past work. See my comment on hsanders answer. –  Scott Chamberlain Jun 20 '12 at 22:36
show 1 more comment

What it does for you is it forces them to generate a rainbow table per user instead of a rainbow table for the whole site to crack your password. It also means they can't just google your hash values, which is the "ultimate rainbow table". It changes the cracking proposition to a much more difficult task.

Google "5f4dcc3b5aa765d61d8327deb882cf99". See what you get (hint it's the MD5 hash of password, and there are thousands of results).

Hashing every passphrase with a different salt is better than using one salt, but one salt is better than no salt at all.

share|improve this answer
5  
I want to emphasize this point. Salts are not supposed to be kept secret, what they are supposed to be used for is to prevent a precomputation attack, so a attacker can do the work ahead of time (or reuse existing work) to crack the password. Adding one salt for the database helps protect you from them precomputing rainbow tables, however once they find out that the hash of "Password1" is 0xDEADBEEF they can check the entire database and anywhere they see 0xDEADBEEF they know that users password. If you use a salt per user "Password1" would be 0xDEADBEEF on one user and 0x12345678 for another. –  Scott Chamberlain Jun 20 '12 at 22:34
add comment

Let me add that you don't want to hash with MD5 or SHA-1. Those were designed to be fast-hashing. Which is the exact opposite of what you want when someone is trying to crack your password list. Hash with bcrypt, that is designed to be slow. This is an option many developers overlook.

Edit: Here's a good article about it.

Edit: Another article says PBKDF2 and scrypt are also good choices.

share|improve this answer
1  
Whatever algorithm someone chooses, they should use salt. Preferably on a per user basis. It makes every cracking proposition that much harder. –  hsanders Jun 20 '12 at 22:12
1  
yep I read that today as well. I had been using sha1 but from now on I'll be sure to use sah256 or 512 or possibly one of the slow hash functions. –  Ryan Jun 20 '12 at 22:13
1  
@hsanders - Agreed. From now on, my auth systems will all use bcrypt-hashed passwords with random salts. –  coding_hero Jun 20 '12 at 22:20
    
bcrypt is a good tool to consider. However, like many articles telling everyone they're wrong, it overstates the case. "It doesn’t affect how fast an attacker can try a candidate password, given the hash and the salt from your database." is true. "Salts Will Not Help You" is completely false. That's why at the end they have to admit, "bcrypt has salts built-in to prevent rainbow table attacks" But he then absurdly claims "I’m not saying salts are without purpose" (remember, this is the same guy who said "Salts Will Not Help You"). Salts do help. They're just not the be-all end-all. –  Matthew Flaschen Jun 20 '12 at 22:23
    
@MatthewFlaschen - Agreed. I linked to him not because I agree with his stance on salts, but because of the info about MD5/SHA1 vs bcrypt. –  coding_hero Jun 20 '12 at 22:26
add comment

Individually salting passwords helps to prevent attacks leveraging an off-line pre-computation step, such as time-memory tradeoffs (raibow tables). This forces the attacker to brute-force the hashes for recoverin a password. This blog post details several password storage strategies, from the least secure to the most secure one.

share|improve this answer
add comment

The salt is for making the password processing different for each user. Otherwise, the attacker who got a copy of your database (you store password hashes precisely because you envision this situation) could optimize his search and attack all the passwords with the same effort than what it takes to break a single password (rainbow tables, like any other precomputed tables, are an incarnation of this concept). With per-user salts, at least, the attacker will pay the full brute-force effort for each password he wants to crack.

(Ideally, you use a per-user salt that you also change whenever the user changes his password. So it really is a per-password salt.)

Salts are only half of the story; you also want the hashing mechanism to be slow (in a configurable way, but very slow nonetheless). A simple hash is too fast, attackers can literally compute billions of them per second.

Use bcrypt. Bcrypt implementations handle the salt generation and usage, and bcrypt can be made as slow as required.

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.