# Encrypted text length in AES

I have created an application that will be able to read any file and encrypt it using AES Encryption. For efficiency, I am reading a block of data, encrypting it and so on. So for decrypting, I just have to read each block and decrypt using the same key to get the data back. This was what I had in mind.

But it turns out that the size of each encrypted block varies, so I am currently saving the encrypted block size before each block into my encrypted file.

And my question is: Is it normal that AES produces encrypted blocks of varying lengths or am I overlooking something?

(I'm using a padding, as my input block size is not always a multiple of the AES block size.)

I faced the same issue when I had used C++ a few years back, and now as3crypto library for an AIR application while implementing the same application.

• Did you find a solution to your problem? If so, could you update us about it? – Paŭlo Ebermann Oct 30 '11 at 17:24
• Are you perhaps treating the encrypted blocks as null-terminated strings? If so, there's your problem: it's quite possible for the output of AES (or, indeed, pretty much any other modern encryption algorithm) to contain null bytes. – Ilmari Karonen Nov 4 '11 at 16:12

AES should always take in and return 128 bit block sizes. On a different point, it sounds like you are using ECB mode and should consider changing to use a stronger block cipher mode, like CBC.

• yes, i am using ECB mode, i will check using CBC mode then. – midhunhk Jul 17 '11 at 3:52

Plain AES is a block cipher, which can only encrypt 128-bit blocks (i.e. 16 bytes at once).

To encrypt longer pieces of data, one would normally create a stream cipher from the block cipher, by using one of several modes of operation. The simplest (and most insecure) one is the electronic code book mode (ECB), which (for the same key) always produces the same ciphertext for the same plaintext block. Normally one thus would use one of the other modes (like CBC, CTR, ...), each having different advantages.

If you need only sequential access to the whole file, any of these modes will do, as you can always decrypt the file sequentially.

If you need some kind of random access to specific parts of the file, you would break it down into parts which each could be accessed individually. Each of them would then be encrypted as essentially a separate stream, i.e. starting with the initialization vector, and including (if necessary) the padding to fill the last 128-block.

You would also want an index to the parts, so you know which part to access.

Alternatively, you could use CTR mode, which essentially allows random access to the file, only knowing the nonce and the block index, without the need to read or decrypt the blocks before or after the desired block.

• so how about the question And my question is: Is it normal that AES produces encrypted blocks of varying lengths or am I overlooking something? Is it possible that an encrypted block contains \0 (i,e, null-terminating byte)? If not, am I correct if I say that the encrypted block has to be always 16-byte long? – 2523fewqf23f Nov 11 '17 at 5:39
• @2523fewqf23f the encryption result can contain zero bytes, yes. (On average, 1/256 of all output bytes would be 0.) So using null-terminated strings for storing encrypted strings is not a good idea. – Paŭlo Ebermann Nov 13 '17 at 12:38

A late answer, but if your data length is called length you can use the length modulus (%) of 128 to determine the final length of the AES encrypted output in bits.

if (length % 128 == 0) output_length = length;
else if (length % 128 != 0) output_length = length + 128 - (length % 128);

• Nearly all wrong. First, as correctly stated a decade ago, it depends on the mode used; not all do any padding. Even for modes that do pad, like CBC, standard schemes like PKCS5/7 always add at least one octet to correctly handle arbitrary data; only unwise, fragile, obsolete schemes like 'add nulls to ASCII text' can leave len%128==0 unchanged. And even that, in the !=0 case, does NOT add +(len%128), it adds +128-(len%128), which is very different. – dave_thompson_085 Apr 25 at 2:53
• "which is very different" -> indeed almost the opposite. I've changed the answer to fix that. – jonnyjandles Apr 26 at 3:48
• All block cipher modes of AES must be padded. Which includes ECB and CBC, the two modes mentioned here in the discussion. Also, why do you mention PKCS5/7? What does the public key infrastructure standard have to do with the cipher implementation of AES? – jonnyjandles Apr 26 at 3:58
• Paulo's answer suggests CTR, which is not block; anyway you say 'AES' with no limitation. PKCS are about publickey crypto but mostly not infrastructure. PKCS5 although mostly about something else additionally specifies a good, safe, general padding for DES-CBC; see RFC2898 6.1. It actually copied this from PEM, and I don't know why people chose to call it PKCS5 padding not PEM padding, but they did and do. PKCS7, also mostly about something else, extended this in the obvious way for other block sizes; see RFC2315 10.3. Some people continued to use the old name, some changed. ... – dave_thompson_085 Apr 27 at 2:36
• ... In fact this has now come full circle. In 2017 PKCS5v2.1 added other ciphers including AES, see RFC8018 B.2, and for padding references CMS RFC5652 of 2009, which is the most recent IETF successor to PKCS7 -- so now (one kind of) PKCS5 padding IS PKCS7 padding. But lots of systems and programs now in use were created before 2017. – dave_thompson_085 Apr 27 at 2:40