4

I'm helping my friend with hashing his passwords, and I've a question - Should he use one secret string as salt for hashing or is it better to have each user its own salt for hashing?

Consider these three hashes:

hash("secretKey777" + password);
hash("secretKey777" + username + password);
hash(username + password);

Which one is the hardest to crack and the safest?

I think it's best to use hash("secretKey777" + username + password); because for each user not only has "secretKey777" as a salt but also its own username. In case code that hashes the passwords leaks, there will be no attack on all the hashes at once - each has will have its own unique salt.

  • 1
    There's some related info here: security.stackexchange.com/questions/58704/… – paj28 Oct 10 '14 at 22:20
  • 2
    Please don't hash passwords yourself. Cryptographers have already built tools that handle all of the details for you. TL;DR: use bcrypt. – Stephen Touset Oct 10 '14 at 22:23
  • Yes a username would be good enough. The point of salting a password is to increase the bruteforce effort by a multiple of however many unique salts there are in the system. Some will insist that salts must be unique, but the point is to increase effort, thus deterring the attacker. – Andrew Hoffman Oct 11 '14 at 3:55
  • See also this ancient answer on SO - stackoverflow.com/a/536756/10080 (it predates security.se...) – AviD Jun 21 '15 at 19:05
  • what if a user change its username? – giammin Nov 2 '16 at 9:43
5

The primary characteristic of a salt is that it should be globally unique for each user's password hash. It need not be secret, and a username will certainly not meet the required criteria of uniqueness. A shared secret string (used for all users) is not a salt, but a pepper, and has not been demonstrated to add any security over unsalted passwords, and so is not a viable option.

One construction that has the property of being particularly likely to be globally unique is random data of reasonable length. The salt doesn't actually need to be random, but a random value, generated individually for each user gives us reasonable assurance that we have the uniqueness we need.

There's a bit more in this answer: What should be used as a salt?

  • 5
    Usernames are usually unique. Why do you say they will not meet the required criteria of uniqueness? – Abe Miessler Oct 10 '14 at 22:29
  • Thanks for the answer. I'm confused about how to use a random value for salt. The problem is ... it's a random value ... I can only generate it once and after I hash the password I no longer know what the salt was. What did I get wrong? – bodacydo Oct 10 '14 at 22:31
  • 1
    @bodacydo, you will generate a random salt value one time and store it in an unencrypted format along with your hashed password. This way you an access the salt whenever authentication needs to take place. – Abe Miessler Oct 10 '14 at 22:32
  • 2
    @AbeMiessler Usernames are not globally unique. The requirement for a salt is not just that it's unique for your application, but it's unique for all applications everywhere. – Xander Oct 10 '14 at 22:34
  • 1
    @AbeMiessler security.stackexchange.com/a/31846/10211 Scroll to the section on Salt Generation. – Ayrx Oct 11 '14 at 2:56
0

Should he use one secret string as salt

No. One hard-coded side wide salt does prevent pre-calculated rainbow table attacks, but those are not really a major concern nowadays. The main advantage of using a random salt for each hashed password is that an attacker when bruteforcing has to hash each password with each salt, instead of just hashing once and checking against all passwords. So it slows the attack down by a factor equal to the number of users.

each user not only has "secretKey777" as a salt but also its own username

Don't use usernames as hashes. It doesn't really impact security[*], but it does have an effect on usability and maintainability. What if a user want's to change their username? This wouldn't be possible with your approach.

[*] except for the point @Xander made. It is an impact, but it is quite low.

So what is the correct approach?

hash(password+ generateRandomSalt());

And store the salt next to username and password in the database. You could also use a library that manages all of this for you (for example if you are using PHP, password_hash uses bcrypt and manages the salts for you).

  • "What if a user wants to change their username?" Require that they enter their password when they change their username, then recalculate and update the salted hash along with the username. Or use whatever long-lasting unique identifier you have for the user, presumably if users change their usernames you have some other immutable ID for them. – MikeFHay Mar 22 '18 at 14:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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