Password hashing with true random salt or username salt plus pepper?

余生长醉 提交于 2019-12-10 09:05:47

问题


Consider the following two methods:

hashedPassword = hash(trulyRandomSalt + password)

Where hashedPassword and the trulyRandomSalt are stored in the database.

hashedPassword = hash(applicationConstantPepper + uniqueUserName + password)

Where the hashedPassword and uniqueUserName are stored in the database and the applicationConstantPepper is stored in the application config. Here, the uniqueUserName acts as a salt which are usually email addresses.

I have read this question which has a lot of great information but doesn't address an application constant pepper value and how that will improve using usernames as a salt.

I have always used method one with a 32 bit cryptographically random salt. However, I've just seen method two used in another application. The first issue I have with method two is that it ties the username to the hash so that the username can never change without regenerating the hash.

What are the security issues with method two? Which would be the best method to use?


回答1:


Consider the following two methods:

The first method is terrible because it allows attackers who get your hashes to use something like oclHashcat to make, typically, trillions or quadrillions of guesses per month, and the second is horrific because those same attackers can not only make the same, typically, trillions or quadrillions of guesses per month, if they get ahold of the applicationConstantPepper and usernames before they get ahold of your passwords, they can precompute guesses while they work on getting your passwords.

Please read How to securely hash passwords?, in which Thomas Pornin states "For peppering to be really applicable, you need to be in a special setup where there is something more than a PC with disks; you need a HSM." Please read the entire article for context, but the gist of it is:

  • Do use PBKDF2 (also known as RFC2898 and PKCS#5v2), BCrypt, or SCrypt.
  • Do not use a single pass of a hash algorithm, regardless of how good your seasonings are.
  • Do use an 8-16 byte cryptographically random salt.
  • Use as high an iteration count/work factor as your machine can handle at peak load without causing users to complain.
  • For PBKDF2 in particular, do not request or use more output bytes than the native size of the hash function.
    • SHA-1 20 bytes
    • SHA-224 28 bytes
    • SHA-256 32 bytes
    • SHA-384 48 bytes
    • SHA-512 64 bytes
  • If you're on a 64-bit system, consider using PBKDF2-HMAC-SHA-384 or PBKDF2-HMAC-SHA-512, which will reduce the margin of superiority an attacker with 2014-vintage GPU's will have over you.

If you like the pepper concept anyway, please read Password Hashing add salt + pepper or is salt enough?, again, Thomas Porrin's answer in particular.




回答2:


Consider the following two methods...

Neither are particularly good....


What are the security issues with method two?

John Steven of OWASP provides one of the better write ups related to password hashing and storage. He takes you through the various threats and explains why things are done in certain ways. See

  • Password Storage Cheat Sheet
  • Secure Password Storage Threat Model

Which would be the best method to use?

hashedPassword = hash(applicationConstantPepper + uniqueUserName + password) does not provide semantic security. That is, using the constant pepper and the username, the adversary could tell if an oracle answered with a random answer or the real answer.

hashedPassword = hash(trulyRandomSalt + password) is probably equivalent to or mildly better than the other proposed method. The per-user random salt has a lot of desirable properties. But it can be improved upon, too.


Finally, why reinvent the wheel? Go to Openwall's Portable PHP password hashing (phpass) and use it. Its written by the author of John the Ripper. Solar Designer keeps up with the state of the art in password cracking, so the library is probably very useful in practice.




回答3:


In addition to Anti-weakpasswords answer, i would like to point out, that both (salt and pepper) have its purposes. If you apply both, then use a random salt and store it in the database (not a derrived one), afterwards encrypt the password-hash with the server-side key (pepper).

I wrote a tutorial in which the pros and cons with the pepper are explained more indepth. Using a server-side key is an advantage, even if the key cannot be protected entirely.




回答4:


Both methods are approximately equal and are fine as long as you're using a good hash (see other answers)

Using a username has the issue that the username can be re-used. This can be a huge problem if you don't include an application specific prefix as the username is probably used many places so there might already be a decent rainbow table for that username.

The "pepper" helps alleviate this issue by requiring the rainbow table to be specific to your application. Now it only becomes an issue if a user changes their password frequently, as now the attacker could get all the old passwords by generating one rainbow table, instead of getting only one password per search. In my opinion this is a nearly negligible downside, as

  1. most people don't change their passwords frequently
  2. the attacker would still have to access the hash for each password they want to crack, so for a one time database breach there would be no difference.
  3. Anyone who changes their passwords very frequently is likely not reusing the same passwords elsewhere so the additional passwords acquired would be less useful.

Overall, from an attacker's standpoint there's not much gain from a target using usernames as salt if combined with pepper to make them unique.



来源:https://stackoverflow.com/questions/22623588/password-hashing-with-true-random-salt-or-username-salt-plus-pepper

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!