Block encryption algorithms, such as AES, will produce output that is a multiple of the algorithm’s block size. For AES, the output is a multiple of 16 bytes. However, this is for the typically used cipher modes “CBC” (Cipher Block Chaining) and “ECB” (Electronic Cookbook).

There are other cipher modes that turn a block algorithm into a stream cipher. See https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation

Namely, the cipher modes are:

  • Counter Mode (ctr)
  • Cipher Feedback (cfb)
  • Output Feedback (ofb)

In C++, for example, any of the above modes can be used with AES to produce output that is exactly the same size as the input.
For example


    CkCrypt2 crypt;

    crypt.put_CryptAlgorithm("aes");
    // Use Counter mode.  Other stream modes are "cfb" and "ofb".
    crypt.put_CipherMode("ctr");
    crypt.put_KeyLength(128);
    crypt.SetEncodedKey("000102030405060708090A0B0C0D0E0F","hex");
    crypt.SetEncodedIV("A0A1A2A3A4A5A6A7A8A9AAABACADAEAF","hex");

    const unsigned char plainText[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 };

    CkByteData data;
    data.append2(plainText,23);

    CkByteData encData;
    crypt.EncryptBytes(data,encData);

    printf("size of encrypted data = %d\n",encData.getSize());
    const unsigned char *pEncData = encData.getData();

IMPORTANT: The output of encryption consists of bytes that resemble random data, where each byte can have any value from 0x00 to 0xFF. DO NOT try to simply assign such binary data to a string (in any programming language). The purpose of binary encodings, such as base64, hex, etc. are to encode binary data in printable us-ascii chars. Thus, if you the desired encrypted output is to be stored in a string, it must be encoded. Hex encoding uses 2 chars per byte (i.e. 0x01 because “01”). Base64 is a more compact string representation of binary bytes.