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?
- Anybody can ask a question
- Anybody can answer
- The best answers are voted up and rise to the top
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:
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.
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.