Suppose we have a master key, and we want to encrypt some file(s). We then generate one-time key for that file, use it to encrypt file contents, and finally encrypt one-time key using master key (with IV, padding and so on). Fairly common scheme, isn't it?

So, we now want to generate one-time key and store it somewhere in the encrypted file. Straightforward approach is to generate one-time key and IV and use some cipher (in my case it's AES in CBC mode) to encrypt one-time key with master key. After that we store IV and encrypted one-time key in some file. This is pretty standard way too.

So in short, we go from unencrypted random value to encrypted one.

But we can also move in reverse direction. We can fill some buffer with random bytes, then pretend that this buffer is serialized one-time key, decrypt one-time key back from that buffer, and use it to encrypt our file. In that case, instead of having two separate procedures for encryption and decryption of one-time keys, we can keep only decryption procedure.

The question: is it okay to use that trick? Any caveats or pitfalls? Any additional constraints applied to RNG used?

Basically, I just want to make sure that such a simplification won't break security.


As long as your RNG is a cryptographically secure RNG (CSRNG), and your encryption scheme of the one-time key does not involve any padding, it is in fact completely equivalent to randomly sample the plaintext of the one-time key or to randomly sample the ciphertext of the one-time key. This follows from the fact that any unpadded encryption scheme is a permutation, and therefore if the plaintext has a uniform random distribution then so must the ciphertext, and vice versa.

  • Actually there is some padding. Data structure for one-time key serialization is as follows: IV (random, not encrypted), one block of random padding, one-time key (with it's IV). File contents is also padded (one block of random data at the beginning, and [0..BLOCK_SIZE) bytes after the end - CBC mode requirement) – Kirill Gamazkov May 22 '14 at 23:50
  • 1
    If your key size is equal to the block size (128 bits), then you can just encrypt the one-time key directly with ECB and you don't need any padding or IV for that, since the key itself is random. You could also encrypt the file contents using CTR mode and an IV of 0, and thereby avoid the need for any random padding or IV for the file contents either. (You will want a MAC for the complete file, though.) – jbms May 23 '14 at 4:03
  • Well, one-time key size is 256 bits, but I can derive several master-keys (from user password), and encrypt each half of the one-time key with it's own master key. And, since one-time key is used, well, only once, then it does make sense to use CTR instead of CBC, and completely get rid of IVs. Thanks for pointing this out. – Kirill Gamazkov May 23 '14 at 10:31
  • Another option is to simply compute an HMAC-SHA256 (using a master key specifically for this purpose) of the 256-bit one-time key data stored in the file, and treat the result as your one-time key. If you need more bits of one-time key than your hash function outputs, you could use HKDF instead of using the hash directly. – jbms May 23 '14 at 19:05

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.