The idea: one block cipher, many blocks
AES is a block cipher: with a key it turns exactly one 16-byte block into another 16-byte block. Real messages are longer, so they are cut into blocks, and a mode of operation says how the blocks are tied together. The cipher is the same in every mode. The mode decides whether patterns leak, whether the same message looks the same twice, and whether changes are caught.
The page encrypts a small picture three ways at once with real AES-128 and the same key. Each cell is one 16-byte block, about 5 RGB pixels, and a ciphertext block is drawn in the colour of its first three bytes. Random bytes look like noise; equal blocks look equal.
ECB and the penguin
ECB (electronic codebook) encrypts each block on its own: C[i] = AES_K(P[i]). It is a fixed lookup table for this key, so the same plaintext block always gives the same ciphertext block. The penguin has only four colours, so its ECB ciphertext has only four different blocks, and the penguin is still plain to see in new colours (Demo: the ECB penguin). The same message sent twice gives the same ciphertext, so an eavesdropper sees repeats (Demo: same image encrypted twice).
CBC: chaining with an IV
CBC (cipher block chaining) XORs each plaintext block with the previous ciphertext block before encrypting it: C[i] = AES_K(P[i] ⊕ C[i−1]). The first block uses a random 16-byte initialization vector (IV), sent in the clear with the message. Two equal blocks now go into AES as different inputs, so they come out different, and a fresh IV makes the whole ciphertext different each time. CBC needs padding to a whole number of blocks and can't encrypt blocks in parallel, because each one waits for the one before.
CTR and GCM: a keystream plus a tag
CTR (counter mode) never puts the message through AES. It encrypts a counter, IV ‖ 2, IV ‖ 3, …, and XORs the output (the keystream) into the plaintext: C[i] = P[i] ⊕ AES_K(IV ‖ i+1). Blocks are independent, so it runs in parallel and needs no padding. GCM (Galois/counter mode) is CTR plus an authentication tag: GHASH, a polynomial hash keyed by H = AES_K(0), runs over the ciphertext (and any extra header data), and the result is encrypted with AES_K(IV ‖ 1) into a 16-byte tag. The receiver recomputes the tag and refuses the message if it differs. That is authenticated encryption (AEAD): secret and tamper-evident in one step.
A flipped bit
Encryption alone does not stop changes. Eve, who has no key, flips one bit of one ciphertext block (Demo: flip one ciphertext bit):
| Mode | What the receiver gets |
|---|---|
| ECB | That block decrypts to random bytes. No warning. |
| CBC | That block is random, and the same bit flips in the next plaintext block. Eve controls that change: the CBC bit-flipping attack. No warning. |
| CTR (no tag) | Exactly that bit flips in the plaintext, a precise edit. No warning. |
| GCM | ✓ The tag does not match, the whole message is rejected, nothing is released. |
CBC without a MAC also leaks through error messages: a server that says "bad padding" lets an attacker decrypt byte by byte (the padding oracle attack).
Never reuse an IV
An IV only helps if it is new for every message under the same key (Demo: reuse the IV (nonce)). With CBC, two messages under one IV encrypt identically up to the first block where they differ, so Eve learns how long a prefix they share. With CTR and GCM it is much worse: the same IV gives the same keystream, and XORing the two ciphertexts cancels it, C ⊕ C′ = P ⊕ P′. Both pictures show through at once, and a repeated GCM nonce also exposes H, which lets Eve forge tags. GCM's 96-bit IV is usually a counter or random; with random IVs, NIST limits one key to 232 messages.
Which mode to use
| ECB | CBC | GCM | |
|---|---|---|---|
| Equal blocks look equal | ✗ yes | ✓ no | ✓ no |
| Same message twice looks the same | ✗ yes | ✓ no (fresh IV) | ✓ no (fresh IV) |
| Detects changes | ✗ no | ✗ no (add a MAC) | ✓ yes, the tag |
| Parallel, no padding | parallel, padding | ✗ serial encryption, padding | ✓ both |
| Damage if the IV repeats | (no IV) | shared prefix leaks | ✗ P ⊕ P′ leaks, tags forgeable |
In practice: use an AEAD mode (AES-GCM or ChaCha20-Poly1305) from a library that picks the nonces for you. TLS 1.3 allows only AEAD ciphers. ECB is never the right choice for data longer than one block. See Inside AES-128 and SHA-256 for what happens inside one AES block, Symmetric vs Asymmetric Encryption for how the shared key gets there, and Encryption vs Hashing for the difference between a cipher and a hash.
What the page leaves out
Padding (PKCS#7) and the padding oracle attack itself; GCM's additional authenticated data (headers that are authenticated but not encrypted); messages that are not a whole number of blocks; how GHASH is computed fast (tables, carry-less multiply instructions); nonce-misuse-resistant modes such as AES-GCM-SIV; other modes (CFB, OFB, XTS for disks, CCM); and real images, where one block holds bytes of several pixels and rows do not line up with blocks.