Salting Your Password: Best Practices?
Solution 1
Prefix or suffix is irrelevant, it's only about adding some entropy and length to the password.
You should consider those three things:
- The salt has to be different for every password you store. (This is quite a common misunderstanding.)
- Use a cryptographically secure random number generator.
- Choose a long enough salt. Think about the birthday problem.
There's an excellent answer by Dave Sherohman to another question why you should use randomly generated salts instead of a user's name (or other personal data). If you follow those suggestions, it really doesn't matter where you put your salt in.
Solution 2
I think it's all semantics. Putting it before or after doesn't matter except against a very specific threat model.
The fact that it's there is supposed to defeat rainbow tables.
The threat model I alluded to would be the scenario where the adversary can have rainbow tables of common salts appended/prepended to the password. (Say the NSA) You're guessing they either have it appended or prepended but not both. That's silly, and it's a poor guess.
It'd be better to assume that they have the capacity to store these rainbow tables, but not, say, tables with strange salts interspersed in the middle of the password. In that narrow case, I would conjecture that interspersed would be best.
Like I said. It's semantics. Pick a different salt per password, a long salt, and include odd characters in it like symbols and ASCII codes: ©¤¡
Solution 3
The real answer, which nobody seems to have touched upon, is that both are wrong. If you are implementing your own crypto, no matter how trivial a part you think you're doing, you are going to make mistakes.
HMAC is a better approach, but even then if you're using something like SHA-1, you've already picked an algorithm which is unsuitable for password hashing due to its design for speed. Use something like bcrypt or possibly scrypt and take the problem out of your hands entirely.
Oh, and don't even think about comparing the resulting hashes for equality with with your programming language or database string comparison utilities. Those compare character by character and short-circuit as false
if a character differs. So now attackers can use statistical methods to try and work out what the hash is, a character at a time.
Solution 4
It shouldn't make any difference. The hash will be no more easily guessable wherever you put the salt. Hash collisions are both rare and unpredictable, by virtue of being intentionally non-linear. If it made a difference to the security, that would suggest a problem with the hashing, not the salting.
Solution 5
If using a cryptographically secure hash, it shouldn't matter whether you pre- or postfix; a point of hashing is that a single bit change in the source data (no matter where) should produce a different hash.
What is important, though, is using long salts, generating them with a proper cryptographic PRNG, and having per-user salts. Storing the per-user salts in your database is not a security issue, using a site-wide hash is.
Related videos on Youtube
Randolpho
They call me a solution architect. Everybody has a different opinion about what that means. To me, it means that I care about both the forest and the trees. I care about the software, and the things the software interacts with, and the things they interact with, and so on; I think about how each piece of the system works with every other piece to solve the problem at hand. I'm also very much a hands-on architect. I like to solve problems with architecture, but I also like to write custom software within that architecture.
Updated on May 28, 2020Comments
-
Randolpho about 4 years
I've always been curious... Which is better when salting a password for hashing: prefix, or postfix? Why? Or does it matter, so long as you salt?
To explain: We all (hopefully) know by now that we should salt a password before we hash it for storage in the database [Edit: So you can avoid things like what happened to Jeff Atwood recently]. Typically this is done by concatenating the salt with the password before passing it through the hashing algorithm. But the examples vary... Some examples prepend the salt before the password. Some examples add the salt after the password. I've even seen some that try to put the salt in the middle.
So which is the better method, and why? Is there a method that decreases the chance of a hash collision? My Googling hasn't turned up a decent analysis on the subject.
Edit: Great answers folks! I'm sorry I could only pick one answer. :)
-
Jacco almost 14 yearsSee also: stackoverflow.com/questions/1645161/…
-
Omu almost 14 yearsyou could use this: encrypto.codeplex.com, that's for .net
-
Randolpho almost 14 years@Omu: Hmm... that uses a 4-byte random salt, and stores it with the hashed password. The latter is clever, but the former... I think that might be a little low. Still, useful if you want quick and dirty password hashing.
-
Omu almost 14 years@Randolpho you can specify the salt size, 4 byte is by default
-
Randolpho almost 14 years@Omu: Ahh, you're correct. I missed that.
-
Maarten Bodewes almost 12 yearsThe best practice is to use a cryptographic function that does the salting for you, using either PBKDF2 (the standard), bcrypt or even scrypt. Thanks to Stephen for pointing that out.
-
CodesInChaos almost 11 yearsPretty much all standard password hashing constructions take care of combining salt and password, so you shouldn't worry about this. If you don't use a standard password hash, migrate to one.
-
CodesInChaos almost 11 years@Omu Bad recommendation. 1) A single iteration of SHA-1 is too fast, you should use at least 10000, and even that's pretty weak. 2) Default salt is too small. 8 bytes is minimum and 16 is recommended.
-
Piotr Dobrogost almost 10 years
-
Shekhar Pankaj over 7 yearsPlease fix the link .Its not working :|
-
Randolpho over 7 years@ShekharPankaj both links in my post still work perfectly for me.
-
-
wowest over 15 yearsAs a non-security guru, I don't really get point 1. Is hashed_pw = hash(canned_salt + login + password) sufficient, or do you need to store your salt along with the password? Any pointers to why?
-
Stefan over 15 yearsI've added a link to an old question, read those answers. Basically, by not using a different random salt per password you're taking an unnecessary security risk, that might be a real problem in the future.
-
Samuel over 15 yearsIf you read his answer, he is saying you should use a random salt versus their username or other user data. Having one side wide random salt is still valid.
-
Stefan over 15 yearsShould be secure enough, unless you have a lot of users and a hacker creates a rainbow table, just for your site.
-
snemarch over 15 yearsSite-wide random salt is bad, since an attacker can precompute rainbow tables and grab your entire user database. If you don't understand this, please don't write login/security systems :) - you NEED per-user salts.
-
MichaelGG over 15 yearsYes, per-user salt. Ideally, with per-user iterations stored (so you can increase the number of iterations used over time). Any decent framework will have this built-in. (.NET has PasswordDeriveBytes which will handle everything for you.)
-
Samuel over 15 yearsYou don't need salts at all. You should have salts. And as to if you need per user salts, it all depends on the incentive for someone to compromise your user accounts. If there is a huge incentive, you need per user since it will be very costly to compromise all users.
-
Samuel over 15 years@onebyone, damn! He's discovered my salt of 'passwordsalt'!
-
Steve Jessop over 15 years"You don't need salts at all" - heck, you don't need hashing at all, if you think you can keep your database secret ;-)
-
snemarch over 15 yearsIf you're designing any kind of security system, it's braindead not using per-user salt. your site might not be super-interesting, but consider users using the same password on multiple sites... trying to keep the database safe tends to fail :)
-
Phil H over 15 yearsOnly if you truncate the result. Anyway, I still stand by the point that it won't make a difference where the salt is, because the point of the hash is to make the relationship between input and output contain no patterns.
-
Adam over 15 years@onebyone valid. I really meant "common" as "all salts under length X in characterset Y" where X, Y are reasonable; say 20 chars and alphanumeric upper/lowercase. Extendable to say all hexadecimal strings under length Z (say 160) since I think a rainbow table of hashed hashes would be useful..
-
Stefan over 15 yearsSalts don't protect against dictionary attacks, only against rainbow-tables. But he's right that it makes such an attack much slower.
-
MichaelGG over 15 yearsYou should double check the description of rounds. The rounds are on a per chunk basis, not the entire message. (Otherwise, hashing streaming data would require rewinding again and again.) But using iterations does prevent the problem onebyone mentions.
-
Adrien about 15 years@Randolpho: Hey, that's my salt, too! What're the odds?
-
Jacco over 14 yearsAnd make sure the salt is non-predictable/Random : stackoverflow.com/questions/1645161/…
-
Jacco almost 14 yearsAs var as I know, BCrypt Hash needs salting, just like any other hashing scheme.
-
Glenn Maynard over 12 yearsOf course salts protect against dictionary attacks, precisely by making them much slower. The use of salts in passwords far predates rainbow tables. Salts were added specifically to slow down dictionary attacks, by preventing attackers from hashing a password once then comparing it against all users.
-
Glenn Maynard over 12 yearsSalting passwords far predates rainbow tables.
-
Erwan Legrand over 10 yearsWrong anwser: an attacker could precompute MD(pass) for many frequently used passwords and then compute MD(pass+salt) very cheaply because message digest work in an incremental way so as to support streaming.
-
Erwan Legrand over 10 yearsAn attacker could precompute MD(pass) for many frequently used passwords and then compute MD(pass+salt) at a cheaper price for every salt in the password database because message digests work in an incremental way so as to support streaming.
-
halloweenlv over 6 yearsRegarding the last paragraph: how could attacker get any info on the exact number of character the comparison has failed? This makes no sense..
-
Stephen Touset over 6 yearsYou're both correct and incorrect. Timing attacks are real and have been repeatedly demonstrated to be viable with frightening accuracy even over variable-latency network connections to determine exactly where the comparison failed. That said, timing attacks are not actually applicable to common password hashes, since it's computationally infeasible to find inputs that only change small parts of the output.
-
Roland about 2 yearsRegarding your last paragraph: any system that does not allow to reuse old passwords does not use salt. This is one of the reasons against password expiration