I'm generating a key & iv with OpenSSL via:

key = OpenSSL::Cipher::Cipher.new('aes-256-cbc').random_key
iv = OpenSSL::Cipher::Cipher.new('aes-256-cbc').random_iv

Then I am running the random key through:

salt = OpenSSL::Random.random_bytes(32)
OpenSSL::PKCS5.pbkdf2_hmac_sha1(key, salt, 2000, cipher.key_len)

My question being, is this overkill or make the random key generated by OpenSSL weaker? Would it be sufficiently secure to just use the key without running it through a pbkdf2 function?

Any advice would be greatly appreciated.


  • $\begingroup$ Yes, it is overkill. It might seem intuitively 'more' secure than just generating a random key, but it buys you no additional protection from any adversary and violates an important principle of crypto design: to keep things as simple as possible. $\endgroup$ – pg1989 Mar 6 '14 at 20:43
  • $\begingroup$ This isn't an answer to the original question, but unless you have specific need for CBC, it's probably a more prudent decision to use an authenticated mode like GCM, EAX, CCM, or CCFB to prevent malicious manipulation of ciphertexts. $\endgroup$ – Stephen Touset Mar 6 '14 at 23:50

PBKDF2 is designed for low-entropy passwords. Assuming your key is generated by a CSPRNG, then running it through PBKDF2 is redundant. I don't, however, believe it could be weaker than the original key.

| improve this answer | |

There ARE a scenarios where adding the pbkdf2_hmac_sha1 step might be damaging to security. That includes an adversary having instrumented that step to log the input as part of another attack; or a successful side-channel attack on that step (e.g. using a less-privileged process on the same CPU).

Multiplying the crypto algorithms increases the attack surface.

It also increases the difficulty there is to try to ascertain that the code is correct, because more code is involved: now we also need to review pbkdf2_hmac_sha1, and make sure that it spits out most of the entropy in its first parameter (that's at least plausible given what I know of PKKDF2, HMAC and SHA-1, and what I guess of aes-256-cbc), and outputs something that is acceptable whenever a OpenSSL::Cipher::Cipher.new('aes-256-cbc').random_key is (that's plausible, but I would be more hesitant with 3DES instead of AES, because it was customary, or even sometime required, that (3)DES keys use odd parity).

Also: if there is reason to fear that the initial key is bad, you should worry about that; and there is little reason to believe that OpenSSL::Random.random_bytes would give better entropy.

In summary: Yes it is overkill, don't do it. If you have concern about some crypto code, repair that code; or use another code base; or try to workaround the issue, but only as a last resort, and after having understood what the issue really is.

As an aside: when I run the first two code lines in my head, my model of what happens is that two objects Cipher suitable for aes-256-cbc are created (each complete with key, IV, and other state variables), and destroyed after their respective key and IV have been copied; that seems like a lot of pointless work. If that's what happens, I would qualify that as a coding mistake, even if it had no adverse effect beyond requiring way too much work.

Also, that whole code would not work if the key of the Cipher object only had opaque access methods.

| improve this answer | |
  • $\begingroup$ Thanks for the thorough response. I believe you are right in regards to the creation of two Cipher objects that are created then discarded. Will fix. $\endgroup$ – mrmanman Mar 7 '14 at 19:00

Considering we have seen unintentional (and intentional?) bugs in crypto recently, I think it would be prudent to chain together different algorithms and sources of entropy, if possible.

| improve this answer | |
  • 2
    $\begingroup$ Creating more complicated ad hoc protocols is not the right solution to this problem. $\endgroup$ – pg1989 Mar 6 '14 at 21: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.