# OpenSSL not producing messages of expected size

I have a 16 byte file, and after encrypting it, its size weirdly changes.

> hexdump -C 1.txt
00000000  61 61 61 61 61 61 61 61  61 61 61 61 61 61 61     |aaaaaaaaaaaaaaa|
0000000f

> openssl enc -v -aes-128-ecb -nosalt -base64 -in 1.txt -out 2.txt

...

bytes written: 45


It becomes 45 bytes.

• Why is it not a multiple of 16, since AES has 16-byte blocks?
• If OpenSSL adds a header of some sort, how large is it, and is it fixed size? I can't find anything in the documentation that mentions this.

You have 16 bytes to encrypt in your file. You did not set -nopad option, therefore, the OpenSSL will use the default padding, PKCS#7. This padding adds characters so that the input is multiple of the block size. If the input is already multiple of the block size then an additional block is added that contains byte 10 16 times. The rule can be simplified as

$$paddingSize=b−(messageLength \bmod b)$$ where $$b$$ is the block length and padding char is char(paddingSize). This will make the input 32 bytes and with the ECB mode, the output (ciphertext) will be 32 bytes, too.

Next, you set the option -base64 this will convert the output to base64. The base64 converted output length can be calculated by formulas. The unpadded base64 output size is $$\lceil 4 \cdot n / 3 \rceil$$ where $$n$$ is the number of characters. $$\lceil 32*4/3 \rceil = 42$$ and this will round up to the multiple of 4 that makes 44 bytes. The below is the hex dump of the output file;

\$hexdump -C 2.txt
00000000  33 53 37 53 43 56 33 4b  69 63 2b 38 65 69 4a 39  |3S7SCV3Kic+8eiJ9|
00000010  34 6a 69 77 76 76 58 2f  67 48 45 6d 62 54 38 57  |4jiwvvX/gHEmbT8W|
00000020  6a 4b 55 6c 64 57 51 43  5a 39 51 3d 0a           |jKUldWQCZ9Q=.|
0000002d


The missing $$45-44=1$$ byte is the 0a character at the end of the ciphertext, it is the line feed character.

Note: Since this is Cryptography, we must say something about the ECB. If there isn't a really special issue to use the ECB, don't use the ECB mode, this is insecure leaks patterns and enables frequency attack. In modern Cryptography we prefer Authenticated Encryption (AE) modes like AES-GCM. To use it with OpenSSL, use -aes-256-gcm option instead of -aes-128-ecb. AE modes provide Confidentiality, Integrity, and Authentication. And, your obligation for the AES-GCM, is never using an IV again. Even a single AES-GCM nonce reuse can be catastrophic.

• "The base65 converted output length can be calculated by formulas." <-- I'm sure that you meant "base64". (Can't edit due to too few characters changed) – Ismael Miguel Feb 13 '20 at 16:24
• @IsmaelMiguel yes, corrected. Thanks. – kelalaka Feb 13 '20 at 16:28
• openssl enc doesn't support any AE mode, including GCM. (The initial release of 1.0.1 failed to give an error in this case, but the output was wrong. Patchlevel 'h' and up give the error message.) However a program using the library could call EVP_get_cipherbyname("aes-256-gcm"). Also using any PBKDF without salt is bad (and EVP_BytesToKey which is OpenSSL's PBKDF below 1.1.1 is worse) but with salt openssl enc does add a 16-byte header to the ciphertext. (There are other Qs on this.) – dave_thompson_085 Feb 14 '20 at 1:37
• @dave_thompson_085 good points. Interestingly, LibreSSL does. – kelalaka Feb 14 '20 at 7:51