I want to encrypt a truly random plaintext (a key file) based on a user password. I'll use PBKDF2-HMAC-SHA256 to generate an encryption key from the password, but I'm wondering if I even need to bother with AES or some other cipher: can I expect good security if I just use PBKDF2 to generate a key equal in length to the plaintext, and XOR them together?
- Anybody can ask a question
- Anybody can answer
- The best answers are voted up and rise to the top
I would use an encryption method designed for the purpose, such as AES Key Wrap.
That said, PBKDF2 uses a PRF internally, so if you specify an iteration count of 1, your suggestion would effectively amount to using a PRF in CTR mode. Since you put the question that way, then, yes, it would be good enough, in the sense that the weakest link would probably be the password and not the encryption scheme.
Edit: Using the PBKDF derived key as a key stream, rather than as a key for a proper symmetric cipher, would obviously require you to treat the Salt value as a nonce (i.e. it has to be different each time you perform the encryption operation). This is not strictly necessary if you use AES in a secure mode of operation - in such case you would get away with leaving the Salt unchanged, but you would OTOH, depending on which mode of operation you use, might have to set the initial state of the mode of operation to a Nonce value. If you use AES Key Wrap, the initial state is a default constant, but for e.g. CTR mode it would be essential to set the initial counter to a nonce.
Don't. Just don't.
You are indeed perceptive enough to note that if the output of PBKDF2 is truly pseudo-random, then XORing it onto data is as secure as the password is. But don't. Really. It's not good hygiene. A KDF is a Key Derivation Function, not a cipher. It's not designed to be used as a cipher, so don't use it as one. Use it to derive keys that you then encrypt with. It's just safer that way.
PBKDF2 is a wrapper for key generation using a string and a PRF (pseudo-random function). You can use any PRF, be it a hash function or a cipher, but hash functions have a nice property of being one-way, and HMACs are a way to strengthen hash functions for purposes such as these.
Nonetheless, if you XOR the PBKDF2 output on your plaintext, you are relying on the security of the hash function for your whole security. If there are itsy-bitsy flaws in the construction that you don't know about, then there are flaws in your crypto. Any bias, non-randomness, distinguisher, and so on is a flaw in your system.
But if you derive a key that can be (e.g.) distinguished from random but nothing more and then throw that into a secure cipher, you have buffered your security by using the staged implementation.
If you need a practical reason, then here's one -- ciphers are faster than hash functions. If you're encrypting data longer than one hash block, then it's faster to use a cipher. Does that make you feel better?
(I'll also add that back in The Crypto Wars, there were plenty of us who noted that you can turn a hash into a cipher pretty much as you described. We don't do that today because of speed and because of crypto hygiene. Use the functions for what they're designed for.)
No it cannot be used to create an OTP as the technical definition of OTP requires that the pad be truely random and the output of PBKDF2 is not true random, only pseudo-random.
Of course you can generate a large pad from a password and xor it with your random plaintext. What you lose though are strong security guarantees. AES has been hammered at by really smart people for a long enough time that we generally accept it as secure. Your protocol, however, has not been analyzed by anyone. I personally wouldn't feel comfortable using it given that fact.