Salting Your Password: Best Practices?

84,010

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:

  1. The salt has to be different for every password you store. (This is quite a common misunderstanding.)
  2. Use a cryptographically secure random number generator.
  3. 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.

Share:
84,010

Related videos on Youtube

Randolpho
Author by

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, 2020

Comments

  • Randolpho
    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
      Jacco almost 14 years
    • Omu
      Omu almost 14 years
      you could use this: encrypto.codeplex.com, that's for .net
    • Randolpho
      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
      Omu almost 14 years
      @Randolpho you can specify the salt size, 4 byte is by default
    • Randolpho
      Randolpho almost 14 years
      @Omu: Ahh, you're correct. I missed that.
    • Maarten Bodewes
      Maarten Bodewes almost 12 years
      The 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
      CodesInChaos almost 11 years
      Pretty 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
      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
      Piotr Dobrogost almost 10 years
    • Shekhar Pankaj
      Shekhar Pankaj over 7 years
      Please fix the link .Its not working :|
    • Randolpho
      Randolpho over 7 years
      @ShekharPankaj both links in my post still work perfectly for me.
  • wowest
    wowest over 15 years
    As 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
    Stefan over 15 years
    I'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
    Samuel over 15 years
    If 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
    Stefan over 15 years
    Should be secure enough, unless you have a lot of users and a hacker creates a rainbow table, just for your site.
  • snemarch
    snemarch over 15 years
    Site-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
    MichaelGG over 15 years
    Yes, 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
    Samuel over 15 years
    You 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
    Samuel over 15 years
    @onebyone, damn! He's discovered my salt of 'passwordsalt'!
  • Steve Jessop
    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
    snemarch over 15 years
    If 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
    Phil H over 15 years
    Only 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
    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
    Stefan over 15 years
    Salts don't protect against dictionary attacks, only against rainbow-tables. But he's right that it makes such an attack much slower.
  • MichaelGG
    MichaelGG over 15 years
    You 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
    Adrien about 15 years
    @Randolpho: Hey, that's my salt, too! What're the odds?
  • Jacco
    Jacco over 14 years
    And make sure the salt is non-predictable/Random : stackoverflow.com/questions/1645161/…
  • Jacco
    Jacco almost 14 years
    As var as I know, BCrypt Hash needs salting, just like any other hashing scheme.
  • Glenn Maynard
    Glenn Maynard over 12 years
    Of 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
    Glenn Maynard over 12 years
    Salting passwords far predates rainbow tables.
  • Erwan Legrand
    Erwan Legrand over 10 years
    Wrong 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
    Erwan Legrand over 10 years
    An 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
    halloweenlv over 6 years
    Regarding 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
    Stephen Touset over 6 years
    You'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
    Roland about 2 years
    Regarding 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