I try to implement aes-128-cfb myself for learning. To confirm whether my implementation is correct, I want to verify it with a well-known library such as OpenSSL. But then I noticed something strange when I try to use OpenSSL to encrypt.

I have file cleartext.txt with the following content:

This is cleartext that will be used to encrypt with OpenSSL.

Then I execute this command

openssl enc -aes-128-cfb -in cleartext.txt -K 48656c6c6f20576f726c642041455321 -iv 72616e646f6d20313662797465206976 -out output.txt

The strange thing is that the output file contains only 60 bytes. AES block is 16 bytes. The expected output size in byte should be multiple of 16. 60 is not multiple of 16.

Did I miss something important here?


Because CFB doesn't require padding similar to CTR and OFB mode of operation. These modes create cipher blocks and one uses the necessary amount from them.

  • In the case of openssl enc -K -iv the IV is not written to the output file output.txt. Therefore it has the same size as the plaintext in bytes; 61 bytes each for my file. In this case, you must handle the IV. Since you are also providing the IV, make sure that it is not used again. Otherwise, a crib-dragging can occur in the CTR mode or OTP's key re-use.

  • In the case of -k/-kfile/-pass, The IV and Key are derived from the key derivation method by using the user's password and the 8-byte random salt.

    OpenSSL first writes file magic of Salted__ then 8-byte salt then the ciphertext into the file. Now the output size is your magic size + salt size + data-size. In my system, 8+8+61 = 77 bytes.

    • If ECB mode is used

      openssl enc -aes-128-ecb -in cleartext.txt -k -pass -out output.txt

    then the size is 80 bytes due to the padding. Of course, ECB doesn't use the IV and one should forget this mode!

    • CBC mode has similar results with ECB.

    • The derived IV size can change according to used encryption algoritm like 8-byte block cipher TDES and Blowfish requires 8-byte IV and 16-byte block ciphers like AES and Twofish requires 16-byte IV.

When using the password one might be careful about the entropy of the password and the used key derivation method. Using a Diceware password is recommended and at least PBKDF2 for the key derivation. OpenSSL provides various method for key derivation

  • 1
    $\begingroup$ Make sense, since it only need to encrypt iv or previous cipher then xor, so it does not require any padding since IV and previous cipher will always be 128 bits. Thanks. it works. $\endgroup$ – invisal Aug 17 '20 at 16:30
  • 1
    $\begingroup$ Except openssl enc -K -iv doesn't write the IV to the file; in this example the plaintext is 60 and the ciphertext is the same. (Since the IV should be different each time, you probably need to write and read it yourself.) openssl enc's default password-based mode (-k/-kfile/-pass or prompt) does write the salt (used to derive both key and IV) in a fixed 16-byte format. $\endgroup$ – dave_thompson_085 Aug 18 '20 at 2:24
  • 1
    $\begingroup$ Still not quite: for PBE the file contains 8-bytes header (Salted__) plus 8-bytes salt regardless of cipher, but derived key and IV size vary with cipher, and mode; except for ECB which you shouldn't use, and GCM which commandline doesn't support, IV is 16 bytes for AES and Camellia but 8 bytes for TDES Blowfish RC5 CAST SEED and IDEA if configured. $\endgroup$ – dave_thompson_085 Aug 19 '20 at 8:29

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.