cipher.ink Write a message

Learn · Technologies we use

Block cipher modes of operation: ECB, CBC, CTR, OFB and GCM

Why a good cipher in a bad mode leaks, with the ECB picture demo on your own image, a diagram of each mode and a table to choose from.

A block cipher such as AES encrypts exactly 16 bytes at a time. Real messages are longer, and the way you string the blocks together matters as much as the cipher. That recipe is the mode of operation. A good cipher in a bad mode leaks the patterns in your data, or lets an attacker change your message undetected. NIST's SP 800-38A defines five modes, ECB, CBC, CFB, OFB and CTR, and GCM (SP 800-38D) adds authentication on top of CTR. Below we show what each does, draw it, and let you watch the worst one at work on a picture of your own.

ECB: the mode you must not use

Electronic Codebook mode encrypts every 16-byte block separately under the same key. It's the obvious thing to do, and it has a fatal property: equal plaintext blocks give equal ciphertext blocks, so the structure of the message shows straight through the encryption.

ECB: each block alone, so equal blocks give equal ciphertextP1E (key K)C1P2E (key K)C2P3E (key K)C3
ECB: no block affects any other.

The demo below shows what that means. It encrypts a picture with AES-128 twice, once in ECB mode and once in CBC mode, each time with a new random key. Press the sample button or drop in a picture of your own (it never leaves your browser).

Drop a picture here, or click to choose one
PNG, JPEG, GIF or WebP; scaled down to 192 pixels, never uploaded
Original
AES-128, ECB mode
AES-128, CBC mode

Nothing you drop here leaves your browser. The picture is read and encrypted in this page only.

The sample picture is 9,216 blocks of 16 bytes (four pixels each) but only 498 different blocks, because large areas of it are a single color. ECB produced exactly 498 different ciphertext blocks, one for each, so the outline of the picture is plainly visible. CBC produced 9,216 different blocks, which look like noise. Nobody found the key and nobody broke the cipher, and the picture still leaked. The same failure hits any data with repeats: a database column, a table of records, a file header.

CBC: chaining the blocks

Cipher Block Chaining XORs each plaintext block with the previous ciphertext block before encrypting it, and the first block with a random starting value, the IV. Equal plaintext blocks no longer give equal ciphertext, because each ciphertext depends on everything before it.

CBC: each block is XORed with the ciphertext block before itIVP1E (key K)C1P2E (key K)C2P3E (key K)C3
CBC: each block is XORed with the previous ciphertext block, so encryption cannot be done in parallel.
  • The IV must be unpredictable, not merely unique, or an attacker who can influence the plaintext can test guesses.
  • It needs padding. The message has to be a whole number of blocks, so it's padded (PKCS#7 appends n bytes of value n). The decryptor checks the padding, and a decryptor that reveals whether the padding was valid can be turned into a decryption oracle. Serge Vaudenay described the attack in 2002, and the POODLE attack on SSL 3.0 in 2014 was a real-world version.
  • It isn't authenticated. Flip a bit in ciphertext block Ci and plaintext block Pi+1 changes in exactly that bit, while Pi turns into garbage. An attacker who knows the plaintext can make targeted changes to one block, paying with one ruined block.
  • Encryption is sequential, but decryption can run in parallel, because every C is already known.

CTR: a stream from a counter

Counter mode never puts the plaintext through the cipher at all. It encrypts a sequence of counter blocks (a nonce followed by 1, 2, 3, …) and XORs the result, the keystream, with the plaintext. That turns the block cipher into a stream cipher.

CTR: a counter goes through the cipher to make a key streamnonce ‖ 1E (key K)P1C1nonce ‖ 2E (key K)P2C2nonce ‖ 3E (key K)P3C3
CTR: blocks are independent, so both encryption and decryption can run in parallel.
  • No padding, any length, fully parallel, and you can jump to any block.
  • A (key, nonce) pair must never repeat. Reuse it and the two ciphertexts XOR to the XOR of the plaintexts, the "two-time pad". The AES playground shows the second message falling out of that.
  • Not authenticated, and malleable: flip a bit of the ciphertext and exactly that bit flips in the plaintext, with nothing else damaged. A "pay $100" can become "pay $900" without knowing the key (authenticated encryption).

OFB and CFB: the older stream modes

Output Feedback runs the cipher on its own output over and over to make the keystream, and XORs the stream with the plaintext. The keystream doesn't depend on the plaintext at all, so you can compute it in advance, but you can't parallelize it, and like CTR it isn't authenticated.

OFB: the cipher is run on its own output to make a key streamIVE (key K)P1C1E (key K)P2C2E (key K)P3C3
OFB: the key stream is built from the cipher feeding on itself.

Cipher Feedback (CFB) feeds the ciphertext back instead, and it's the self-synchronizing cousin. Neither sees much use now, but OFB has a place in this site's history. Every message sealed here between 2016 and 2026 used AES-256 in OFB, and the browser's Web Crypto API has no OFB, so we open them by encrypting zero blocks in CBC mode, which produces exactly the OFB keystream (how we decrypt 2016 messages with a mode the browser does not have).

GCM: CTR with a seal

Galois/Counter Mode is CTR for confidentiality plus a polynomial hash, GHASH, over the ciphertext (and any extra data you want to bind to it), which yields a 128-bit authentication tag. On opening, the tag is checked first. A wrong key, a flipped bit or a truncated message is refused outright, which closes CTR's malleability problem. This is authenticated encryption, and it's what everything new should use. GCM keeps CTR's rules with a stricter edge: a (key, nonce) pair used twice breaks confidentiality and also leaks the authentication key. The full story is in AES-GCM, explained. NIST's rule for GCM with randomly chosen 96-bit IVs is to use no more than 232 messages under one key, because the chance that two random IVs collide grows with the square of the count. Below that the risk is negligible, and above it the key must be replaced. In the browser, CTR has a related knob: Web Crypto's AES-CTR takes a length that says how many bits at the end of the counter block count up, and the rest is the fixed nonce, so a counter that wraps around repeats the keystream.

The modes side by side

ModeEncrypt in parallel?Decrypt in parallel?Padding needed?IV / nonceAuthenticated?In Web Crypto?
ECBYesYesYesNoneNoNo
CBCNoYesYesUnpredictable IVNoYes
CFBNoYesNoUnique IVNoNo
OFBNoNoNoUnique IVNoNo
CTRYesYesNoUnique nonceNoYes
GCMYesYesNoUnique nonceYes (128-bit tag)Yes

Choosing a mode

For new work, use an authenticated mode: AES-GCM, or a different cipher with the same kind of guarantee, such as ChaCha20-Poly1305. If you have to use CBC or CTR, add a MAC over the ciphertext and verify it before decrypting anything (encrypt-then-MAC). Never use ECB for anything longer than one block. Disk encryption uses a further family, XTS, designed for data stored in place that can't grow a tag, and it's outside the scope of this page.

How cipher.ink uses this

Every message sealed today uses AES-256 in GCM mode, with a fresh random 12 bytes (96 bits) IV per message and per attachment, and a 128-bit tag. The messages sealed from 2016 to 2026 used OFB and are read through the CBC trick above, and that article states the format's weaknesses openly. The only unauthenticated format on this site is that legacy one, kept so old messages still open, and we use ECB nowhere.

On the timeline

  • 2014 The POODLE attack exploits CBC padding in SSL 3.0; Google and Apple redesign phone encryption.

Further reading

  1. NIST SP 800-38A: Recommendation for Block Cipher Modes of Operation (2001)
  2. NIST SP 800-38D: Recommendation for GCM and GMAC (2007)
  3. Vaudenay: Security Flaws Induced by CBC Padding (2002)
  4. Wikipedia: Block cipher mode of operation