# How to encrypt with CBC, step by step?

I have this message "Hello from another world"

1. Can you explain how to encrypt it with CBC step by step?

2. Are the message characters H, E, L, L, O .. converted to binary first, then every 8 bits or 16 bits XORed with IV and passed to the encryption function to be encrypted with a secret key?

• What do you mean by "characters ... converted to binary"? If the message uses ASCII or UTF-8 encoding, the "H" character is represented by 8 bits. If the message uses UTF-16 encoding, the "H" character is represented by 16 bits. You can see any message as a stream of bits. No any conversion is needed for this. Feb 11 at 13:55

The message to encipher is expressed as bytes per some agreed-upon character encoding. Nowadays that's usually UTF-8. Here Hello from another world is 24 characters part of the ASCII subset of UTF-8, thus each character is encoded as a single byte, thus there are 24 bytes. In hexadecimal they are:

48 65 6C 6C 6F 20 66 72 6F 6D 20 61 6E 6F 74 68 65 72 20 77 6F 72 6C 64


The question is tagged AES, thus we are using a block cipher with a 128-bit (16-byte) block.

CBC itself can only encrypt a whole number of blocks, thus any message consisting of characters or bytes must be padded (including if it's size in bytes is multiple of the block size). There are several methods for this. A popular one (PKCS#7) is to pad an $$n$$-byte messages for a cipher with $$b$$-byte blocks using $$p=b-(n\bmod b)$$ bytes having the value $$p$$. Here $$n=24$$, $$b=16$$, thus we add $$p=8$$ bytes with the value 08, and the padded message now consists of the two blocks $$P_1$$ and $$P_2$$

48 65 6C 6C 6F 20 66 72 6F 6D 20 61 6E 6F 74 68
65 72 20 77 6F 72 6C 64 08 08 08 08 08 08 08 08


In CBC mode, we need a random Initialization Vector the size of a block, chosen randomly by the encrypting side at start of encryption of each message, and transmitted in clear to the receiving side (usually as the first block of ciphertext). We'll assume the IV is, in hexadecimal:

55 A6 42 03 51 80 44 B0 E9 38 3C EE 67 36 A9 62


If we note the IV $$C_0$$, CBC enciphers per $$C_i=E_K(C_{i-1}\oplus P_i)$$ for each block of plaintext $$i$$, where $$\oplus$$ is eXclusive-OR, and $$E_K$$ is block encryption of one block with key $$K$$ (here AES encryption with a 128, 192 or 256-bit key)

If we used AES-128 with key (in hexadecimal)

B8 36 6C 65 00 A1 E6 FF 3D 56 8C EA 94 9F A8 14


the complete cryptogram is thus IV plus two ciphertext blocks, totaling 48 bytes:

55 A6 42 03 51 80 44 B0 E9 38 3C EE 67 36 A9 62
B6 48 C2 78 40 D4 2C A9 85 16 49 C5 A6 13 32 BC
AE 08 C2 FD 0A DE B6 79 98 2F D6 B6 1A D9 1D 2C


Depending on application, this cryptogram is sent as bytes, or encoded in hexadecimal (as above), Base64…, or/and with some further formatting such as ASN.1, JSON or XML; such encoding is not part of CBC.

On the receiving side, decryption is per $$P_i=D_K(C_i)\oplus C_{i-1}$$, yielding two blocks. The padding is removed; for PKCS#7, by removing the last byte $$\ell$$ of the last deciphered block, then further removing the last $$(\ell-1)\bmod b$$ bytes (in order to lessen the risk of padding oracle attack, it is recommendable to not check the padding further). Here with $$b=16$$ this removes in total $$1$$ to $$16$$ bytes, according only to the low-order four bits of the last byte.

• "First the message is transformed into bytes" - This is not correct. Any message in computer is already represented by a stream of bytes. Feb 11 at 14:56