Is the password hash (with bcrypt) better when You concatenate the username with password?

For example:

$this->hash($username . $password);



Last time I used sha1($username . $password), but now when creating a new project I want to know does it really matter? Does it increase its encryption strength?


Usernames are not very good at salts because they are not unique worldwide, and neither are they timewise.

The salt is meant to prevent an attacker from optimizing his research by attacking several password hashes "in parallel" and sharing the computational cost. "Parallelism" is a rather wide term; it does not necessarily mean "simultaneously". For instance, a precomputed table (e.g. rainbow table) of password-to-hash values is a kind of parallelism (I am just reasoning in space-time without distinguishing the time dimension from the three space dimensions here).

In practice, if your software uses the username as salt, like you suggest, then it becomes worthwhile to precompute a table for attacking the password of admin because chances are that many (most ?) servers using your software will have a user named admin. That's a breach of "worldwide uniqueness": user names are unique on a given server but not over all existing servers which use this software or a similar software, which allows for attack optimizations.

As for "timewise" uniqueness, I allude to a user changing his password. If the user name is the salt, then the old and the new password will use the same salt, and thus could be attacked in parallel for less than twice the cost of attacking one password. Old passwords are valuable for attackers, because:

  • When users change their password, they tend to use "guessable series" (i.e. if an old password of a user is "Password201207" then chances are that the new password, if chosen around Christmas, would be "Password201212").

  • Some users recycle passwords: when they change their password, often because of a change password policy enforced by the sysadmin, they walk through a short list of passwords and cycle; an old password could be the password they will use when they next change their password.

  • Users being users, they reuse passwords between sites (thus the old password on a server could be the current password for the same user on another site).

For these reasons, user names are not good salts.

Mandatory note: salting is only one part of the issue; you also need the password hashing to be slow. A single SHA-1 invocation is way too fast; an attacker with a couple GPU will compute one billion of those per second. The salts prevent the attacker from reusing the effort of cracking one password over another, but you also need the effort of cracking a single password to be non-negligible. Good password hashing functions are a tricky thing. Use bcrypt and refrain from designing your own schemes.

| improve this answer | |

What you are describing is a Salt. The primary purpose of having a salt is to protect against rainbow table attacks. Ideally though, the salt should be randomly generated, and not be derived from the username.

| improve this answer | |
  • 2
    I would add that doing bcrypt(username+password, salt) is a nice way to avoid having to check that every salt is unique, assuming your usernames are unique. – Polynomial Jul 5 '12 at 15:29
  • 1
    As salt, random string is perfect, email is excellent, username is good, numeric, auto_incrementing userID is bad (too predictable). I'd recommend using email as salt if you want to save some space (compared to random salt, which you need to store), just make sure you update the passwordHash field when user changes email. – Matrix Jul 5 '12 at 15:32
  • 1
    @Matrix - It would be a much better idea to use a random salt unique to each user. This is after of course you make sure the password the user wants to use is not a common password. – Ramhound Jul 5 '12 at 15:47
  • 3
    @Matrix The question is, just how much storage will the random string take up? Not a lot. Is it worth the added security provided by the randomness? I'd say yes. – user10211 Jul 6 '12 at 0:43
  • 3
    email and username are NOT good salt values. They fail at being unique across systems. The salt should be unique and non-predicatbale. This is meant worldwide. Best practice: use a random set of bytes with an unpredictable random generator, preferably within a salt space large enough to make collisions improbable. It is tempting to try to derive a salt from some data which is "presumably unique", but such schemes often fail due to some overlooked details. Since it is comparatively easy to creating sufficiently random salt value, stick to the best practice. – Jacco Jul 9 '12 at 12:56

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.