For a login the user credentials are typically some form of "username" and a matching "password".

The password is (hopefully) stored as a hash in the database.

But what about the username?

Is the username stored as a plaintext in the database?

Would it be a good idea to hash both the username and the password?

  • $\begingroup$ How would you obtain the hashed password if the username is hashed as well? $\endgroup$
    – SEJPM
    May 4, 2018 at 9:37
  • $\begingroup$ I guess you could search the database after the username is hashed and then compare the hashed passwords as usual, but I see your point... $\endgroup$ May 4, 2018 at 9:45

2 Answers 2


If username was treated as the password should be, like salad (salt, pepper, hash, toss / en Français saler, poivrer, hacher, touiller), then

  • If there is salt, it can't be directly inferred from username. And the alternatives are getting rid of salt (allowing pre-computation and rainbow tables), or test all users (which is going to be prohibitively costly for more than a few users).
  • If the username doubles as storage of the email, then we can no longer readily send an email to all users. And if we can send such general email, there is the risk that likely usernames can be inferred from email.
  • Username is even more guessable than password, and (unless treated as an extension of password) if can be found even more easily.

For these reasons, it is typically functionally unacceptable to apply a password hash to username.


Instead of storing (username, salt, hash(salt, password)) you can store in one table (username, salt) and another (hash(salt, password, username)). This is no more secure than hash(salt, password) if salts (plural) are unique. (Which they should be. You then force attacks on individual accounts instead of the whole group. A cracker checking offline for hash("unique per user salt", "password1") gets less information than when they can get hash("global salt", "password1"), which yields the set of all users that have that password.)

If you have only a site-global password salt (you should instead do per user) then storing (hash(global salt, password, user name)) is better than (hash(global salt, password)) for similar reasons.

One small problem with the global salt scheme is that leaks some information if a user starts with say "password1", changes it to "password2", then back to "password1" again. In that case someone who had previous cracked that user's first password that person will see that the hash for the old username password combination is still in the database. They then know that they can use a users old password again. (I would assume they would try the user's old password and variations on that password anyway, if they crack the user's old password, however.) Use a new unique salt (random with enough entropy that collisions are unlikely) every time a person changes their username or password to prevent that.

From a non-crypto point of view the (username, salt, password hash) construct has the benefit that it only needs one query with one unit of latency. The other you need to wait one unit of time to get (username, salt) back and another for (hash of username salt and password) to be checked (and reported back whether its present or absent (which can still be done O(1) time with a hash table (the data structure) index)). Of course if you're using password stretching or infrequently do authentication checks then that extra latency is insignificant.

  • 1
    $\begingroup$ A global salt is no longer a salt, it is some sort of pepper. $\endgroup$
    – forest
    May 8, 2018 at 3:13
  • $\begingroup$ That's reasonable. I think it's usually only called pepper if it's secret or at least separate from the database. I wanted to be explicit because I worry people do/will mistakenly do salts that way. $\endgroup$ May 8, 2018 at 5:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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