4
$\begingroup$

I need to derive a key from a username and a password. These are the only two things I have access to. What I thought is using PBKDF2 with username as the salt and password as the master password.

Could someone help me evaluate / confirm this solution in terms of security?

Update: Since the salts are required to be unique, I have thought about using the following as a salt:

HASH(USERNAME) XOR SOME_GLOBAL_CONSTANT

or perhaps

HMAC(SOME_GLOBAL_CONSTANT, USERNAME)

What do you think of this updated salt value?

$\endgroup$

2 Answers 2

6
$\begingroup$

That's a reasonable solution if you can't use a random salt. If you personalize your hash function for your application, then the salt is globally unique for each user. (e.g. use sitename||username as salt) The only salt reuse happening is that older passwords of the same user have the same salt. But that's a very minor issue.

I disagree with Polynomial who wants unpredictable salts. Unpredictability is not necessary for most protocols involving password hashing. Global uniqueness or at least rareness is the decisive property.

To combine sitename and username I'd simply go with concatenating them. Your HMAC suggestion is certainly fine too. Your xor variant gives me a bit of a bad feeling, but is probably fine too.

$\endgroup$
2
  • $\begingroup$ Thank you @CodeInChaos, I have made an update to my question to satisfy the global uniqueness requirement. What do you think? $\endgroup$ Jul 10, 2012 at 13:48
  • 2
    $\begingroup$ I second that your scheme works, even though the salt is predictable. It useful and simple (and to a degree safer) to use the concatenation of your own constant and user name as salt (this fully prevents a cracking effort on another system to be reusable on yours, even if that constant is public). However, scrypt would be widely preferable to PBKDF2. See the table there or Stronger Key Derivation via Sequential Memory-Hard Functions. $\endgroup$
    – fgrieu
    Jul 10, 2012 at 17:01
2
$\begingroup$

This is a bad idea, explored a little in a question on Security SE.

A salt should be:

  • Unpredictable.
  • Unique, at least in your database and ideally worldwide.

It does not need to be secret.

A username is not unpredictable, and only just satisfies the uniqueness requirement.

A much better solution is to randomly generate the salt and verify that it doesn't match any salt you've already used. If verifying uniqueness is difficult, you could hash the username with a random salt concatenated, to get your final salt. This isn't bulletproof, but it does help reduce collisions.

$\endgroup$
5
  • $\begingroup$ Can you justify your unpredictability requirement? $\endgroup$ Jul 10, 2012 at 13:41
  • $\begingroup$ The linked question is pretty different from this one, since it derives the salt solely from the thing being hashed. Which is equivalent to not using a salt at all. $\endgroup$ Jul 10, 2012 at 13:42
  • $\begingroup$ @CodeInChaos If the salt is predictable (e.g. user ID from database auto-increment) an attacker could trivially generate small rainbow tables for each user. $\endgroup$
    – Polynomial
    Jul 10, 2012 at 13:54
  • 1
    $\begingroup$ The only advantage of that over a direct brute-force is that it can be done before the leak. It doesn't reduce the total work an attacker has to do at all. $\endgroup$ Jul 10, 2012 at 13:57
  • $\begingroup$ @CodeInChaos In terms of theory, I'd agree with you. In practice, however, forcing the attacker to wait until he has breached the database is useful. It gives you time to respond to an incident. $\endgroup$
    – Polynomial
    Jul 10, 2012 at 14:07

Your Answer

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

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