What is the best way to generate two independent symmetric keys from one user-entered password or passphrase? Would using both scrypt and pbkdf2 achieve this?


Yes, scrypt achieves this. Scrypt has a variable-length output, so just generate as much output as you need. For instance, you can ask it for 256 bits of output, then use the first 128 bits for one key and the second 128 bits for the other key.

While PBKDF2 also has a variable-length output, I do not recommend that you use it in the same way. It has a subtle disadvantage/weakness which slightly reduces its available security if you ask it to generate more than one block of output. Instead, I recommend that you use PBKDF2 like this:

Kt = PBKDF2(..., passphrase, salt, n, 128)
(K1, K2) = PBKDF2(..., Kt, salt, 1, 256)

In other words, use PBKDF2 with lots of iterations (choose $n$ to be large) to generate a 128-bit temporary key $Kt$; then use PBKDF2 a second time to stretch $Kt$ into 256 bits of pseudorandom output, and use that to form the keys.

What's wrong with just asking PBKDF2 to give you 256 bits of output? It turns out that, due to a subtle issue, this may let an attacker get a 2x speedup. Or, another way to think about: it forces legitimate users to do twice as much work as they ought to, which means you can't push the iteration count up quite as high as you should, so you get weaker security than you could have gotten. The subtle issue is described at a high level in this Ars Technica article; a blog post has more technical details, as does an explanation from 1password.

Basically, the issue is that with PBKDF2, an attacker who wants to test a guess at your password can generate just the first 128 bits of the 256-bit output twice as fast as generating the whole thing, and the first 128 bits may be enough to verify whether the guess is correct. Scrypt does not have this issue (when used with typical parameters), so with scrypt, you can just ask it for 256 bits and you'll be fine.

Don't try to use both. There's no need to use both scrypt and PBKDF2; and if you do use both (scrypt to generate one key, PBKDF2 to generate the other), then you will have introduced the same subtle weakness described above, just in a slightly different guise.

Bottom line recommendation. If this sounds too complicated: just use scrypt, and ask scrypt for as much output as you need. You can ignore all the rest.

  • $\begingroup$ Or I was thinking ... generate 256 bits from scrypt or pbkdf and use the first bit in the first key the second bit in the second key and so on ... That could work right? $\endgroup$ May 8 '13 at 12:18
  • $\begingroup$ I appreciate that this answer included both the PBKDF2 flaw and the warning about using two KDFs six years ago! I always try to mention that if it's relevant to a question. (I also mention that Argon2 doesn't have the flaw that PBKDF2 has and that now Argon2 should be the default choice for password stretching.) The 128-bit number, though, is a variable that depends on what PRF PBKDF2 uses. It's 512 bits instead if someone is using HMAC-SHA-512, for example. $\endgroup$ Dec 2 '19 at 1:46

Both scrypt and pbkdf2 have variable length outputs, and each bit of the output is effectively independent on every other bit. So, one obvious way would be just to ask for enough output for both keys. For example, if the two keys are each 128 bits, then ask scrypt (or pbkdf2) for 256 bits of output; use the first 128 bits as the first key, and the second 128 bits as the second key.

  • $\begingroup$ I was thinking for a 128 bit key to use pbkdf with 128 output and scrypt to generate the other key $\endgroup$ May 4 '13 at 16:38
  • 2
    $\begingroup$ Why? Using one algorithm is less complicated and has equivalent characteristics. $\endgroup$ May 4 '13 at 22:23
  • $\begingroup$ poncho - Actually, there is a bit of an issue with your advice about pbkdf2. See my answer for details. $\endgroup$
    – D.W.
    May 5 '13 at 20:48

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.