Why This Matters
Mode choice is the most commonly misunderstood AES decision. ECB mode is still found in production systems in 2026. Choosing the wrong mode can render AES encryption completely ineffective — leaking plaintext structure, enabling bit-flip attacks, or allowing full plaintext recovery through padding oracles.
Which mode should I use?
- General-purpose / HTTPS / app data? → AES-GCM AEAD, fast, hardware-accelerated
- Constrained device / IoT / 802.15.4 / BLE? → AES-CCM AEAD, small code footprint
- Legacy interop only, and you can add a MAC? → AES-CBC + HMAC (Encrypt-then-MAC) never CBC alone
- Multi-block data with ECB? → NEVER leaks structure (see the penguin)
ECB: The Dangerous Default
AVOIDElectronic Codebook mode encrypts each block independently with the same key. Identical plaintext blocks produce identical ciphertext blocks, leaking the structure of the message. As defined in NIST SP 800-38A, ECB should never be used for multi-block data.
Key (hex)
Ciphertext (hex)
Block Comparison
Same color = identical ciphertext block (structure leaked) Different color = different ciphertext block
ECB Penguin Effect
Original
ECB Encrypted
Decrypt
Try decrypting with the correct key vs. tampered ciphertext. ECB has no integrity check — tampered ciphertext decrypts without error.
An attacker who sees the ciphertext CAN
- See which plaintext blocks repeat (block-equality leak)
- Recognize known images, templates, or protocol structure
- Splice or reorder ciphertext blocks without detection
An attacker CANNOT
- Decrypt a single random block without the key (still AES)
- Recover the AES key from ciphertext alone
Why ECB Is Never Appropriate
ECB encrypts each 16-byte block independently. This means repeated plaintext blocks always produce repeated ciphertext blocks. An attacker learns where repetition occurs — destroying confidentiality for structured data like images, database fields, or protocol messages.
Real-world incidents: the famous ECB penguin illustrates the leak; early WEP and several enterprise SSO cookies have shipped ECB and been broken in production.
Implementation note: WebCrypto does not support ECB natively. This demo implements ECB by encrypting each 16-byte block individually using AES-CBC with a zero IV, which for a single block is equivalent to ECB encryption. This approach is documented honestly — ECB is shown only to demonstrate why it must be avoided.
Self-check
Which property of ECB lets the penguin silhouette survive encryption?
CBC: The Classic Workhorse
LEGACYCipher Block Chaining mode XORs each plaintext block with the previous ciphertext block before encryption. As defined in NIST SP 800-38A, CBC requires a unique, unpredictable IV for each encryption and provides confidentiality but not integrity.
Key (hex)
IV (hex)
Ciphertext (hex)
Block Chaining Visualization
Vulnerability Demo
Decrypt
CBC needs the same key AND the same IV to decrypt. Try all four variants and watch what survives.
An attacker who sees the ciphertext CAN
- Flip bits in one block to flip the SAME bits in the next plaintext block
- Mount a padding oracle attack to recover the full plaintext (see Oracle tab)
- Modify ciphertext silently — there is no authentication tag
- Detect identical messages if the IV is reused
An attacker CANNOT
- Decrypt without the key
- Recover the key from ciphertext + IV
- Forge ciphertext IF Encrypt-then-MAC is correctly applied
CBC Vulnerabilities
IV reuse: Same plaintext + same IV + same key = identical ciphertext. The IV must be unpredictable for each encryption.
Bit-flip attack: Flipping bit i of ciphertext block n flips bit i of plaintext block n+1 — enabling controlled plaintext manipulation without knowing the key.
No integrity: CBC provides confidentiality only. Without a MAC (e.g., HMAC in Encrypt-then-MAC), ciphertext tampering goes undetected. This is why AEAD modes like GCM replaced CBC.
Real-world incidents: BEAST (2011) — predictable IV in TLS 1.0 CBC records; Lucky 13 (2013) — timing-based padding oracle on TLS; POODLE (2014) — SSL 3.0 padding oracle.
Self-check
You inherit a legacy system that must keep using AES-CBC. What's the minimum you should add to make it safe against bit-flips and padding oracles?
CTR: Stream Mode
ACCEPTABLECounter mode turns AES into a stream cipher by encrypting successive counter values to produce a keystream, then XORing with plaintext. As defined in NIST SP 800-38A, CTR requires a unique nonce/counter combination for every encryption — nonce reuse is catastrophic.
Key (hex)
Counter/Nonce (hex)
Ciphertext 1 (hex)
Counter + Keystream Generation
Nonce Reuse Attack
Decrypt
CTR has no integrity check. A single bit flip in ciphertext byte n flips the exact same bit in plaintext byte n — and decryption "succeeds" silently.
An attacker CAN
- If nonce reuses: recover full plaintext via C₁ ⊕ C₂ = P₁ ⊕ P₂
- Flip any bit of ciphertext and flip the same bit of plaintext (no integrity)
- Truncate the ciphertext silently
An attacker CANNOT
- Decrypt without the key (when nonces are unique)
- Predict the keystream for an unused counter value
Nonce Discipline Is Everything
If two messages are encrypted with the same key and nonce, XORing the two ciphertexts cancels out the keystream: C₁ ⊕ C₂ = P₁ ⊕ P₂. An attacker who knows (or guesses) one plaintext can recover the other. CTR is secure only when every (key, nonce) pair is unique.
Real-world incident: Nintendo Switch boot ROM (2018) reused CTR nonces in early production; multiple academic case studies have similar findings for hand-rolled CTR.
Self-check
Two CTR messages were encrypted with the same key and same nonce. What does the attacker get from XORing the two ciphertexts?
GCM: Authenticated Encryption
RECOMMENDEDGalois/Counter Mode combines CTR encryption with GHASH authentication. As defined in NIST SP 800-38D, GCM provides both confidentiality and authenticity, including authentication of Additional Authenticated Data (AAD). The nonce must never repeat with the same key.
Key (hex)
Nonce (hex, 12 bytes)
Ciphertext (hex)
Auth Tag (hex)
Tamper Detection
Decrypt
GCM's authentication tag binds ciphertext, AAD, nonce, and lengths. Any modification → decrypt fails. This is what "AEAD" buys you.
An attacker CAN
- If nonce reuses: forge messages and recover the GHASH subkey H ("forbidden attack")
- Make the receiver reject messages by tampering — denial of service
- Try ~2tagbits forgeries per message if the tag is truncated
An attacker CANNOT
- Modify ciphertext, AAD, or nonce without detection
- Decrypt without the key
- Mount a padding oracle attack (no padding, no oracle)
Why GCM Is the Recommended Default
GCM provides authenticated encryption — any modification to the ciphertext, AAD, nonce, or tag causes decryption to fail. This prevents bit-flip attacks, padding oracle attacks, and all forms of ciphertext tampering.
Tag truncation: Per NIST SP 800-38D §5.2.1.2, truncating the authentication tag below 128 bits reduces the effort required for a forgery attack. A t-bit tag provides at most 2−t forgery probability per attempt. Tags shorter than 96 bits are not recommended.
Real-world incident: the "forbidden attack" (Joux, 2006) — if a GCM nonce ever repeats, the attacker can recover H and forge arbitrary ciphertexts; multiple HTTPS frontends shipped repeating nonces before this was widely audited.
Self-check
You reuse a GCM nonce with the same key. What's the worst consequence?
CCM: Constrained Environments
ACCEPTABLECounter with CBC-MAC mode combines CTR encryption with CBC-MAC authentication. Defined in RFC 3610 and NIST SP 800-38C, CCM is a two-pass AEAD mode suitable for constrained environments where code size and complexity matter.
Key (hex)
Nonce (hex)
Ciphertext + Tag (hex)
CCM vs GCM Comparison
Tamper Detection
Decrypt
Like GCM, CCM is an AEAD — tampering is rejected outright.
An attacker CAN
- If nonce reuses: forge messages (same caveat as GCM, less catastrophic)
- Cause denial of service via rejected tampered messages
An attacker CANNOT
- Modify ciphertext, AAD, nonce, or length without detection
- Mount a padding oracle attack
- Decrypt without the key
When to Use CCM
CCM is specified in RFC 3610 and used in IEEE 802.15.4 (Zigbee), Bluetooth Low Energy, and other constrained protocols. It uses only the AES block cipher — no dedicated hash or GHASH — making it suitable for hardware with minimal gate count.
For general-purpose applications, GCM is preferred due to its single-pass operation and hardware acceleration support (PCLMULQDQ/CLMUL instructions).
Real-world deployments: WPA2 (CCMP), Zigbee, BLE link-layer security — all chose CCM for its small code/hardware footprint.
Implementation note: WebCrypto does not support CCM. This demo implements CCM from AES block primitives using @noble/ciphers ECB for single-block AES encryption, building CBC-MAC + CTR per RFC 3610.
Self-check
What is the main reason Zigbee/BLE/802.15.4 chose CCM over GCM?
Same plaintext, all five modes
SIDE-BY-SIDEType any plaintext (try one with repeated 16-byte blocks). The lab encrypts it under ECB, CBC, CTR, GCM, and CCM with fresh random keys/nonces and renders the ciphertext block grids side-by-side. ECB will show repeats; the others won't.
What to look for
ECB: repeated input blocks → repeated colored squares. Structure leaked.
CBC / CTR / GCM / CCM: every block looks unique even when the input repeats. That's chaining or keystream doing its job.
Look at the legend at the bottom of each row — only ECB will report duplicate blocks.
Padding Oracle Attack
ATTACK DEMOA step-by-step demonstration of a CBC padding oracle attack. The oracle reveals only whether PKCS#7 padding is valid — yet this single bit of information is enough to recover the entire plaintext, one byte at a time.
Target Ciphertext (hex)
Attack Progress
Recovered Plaintext
Latest XOR derivation
Oracle Query Log
An attacker who has oracle access CAN
- Recover the entire plaintext byte-by-byte with ~128 queries per byte
- Do all of this with NO knowledge of the key
- Operate without arousing suspicion (queries look like normal traffic)
An attacker CANNOT
- Recover the key itself
- Succeed against a system that uses AEAD (GCM/CCM)
- Succeed against Encrypt-then-MAC that verifies the MAC first
Why This Attack Works
PKCS#7 padding requires the last n bytes to all equal n. A padding oracle — any system that reveals whether padding is valid — leaks one plaintext byte per ~128 queries on average. Across 16 bytes per block, the entire plaintext is recovered using only ~2,048 oracle queries per block.
Per-byte math: when guess g produces valid padding with target pad value p, then intermediate = g XOR p. The plaintext byte is then intermediate XOR prev[byte], where prev is the real previous ciphertext block (or the IV for block 0). The XOR derivation panel below shows each successful step live.
Real-world incidents: Lucky 13 (2013) — timing-based oracle in TLS; POODLE (2014) — SSL 3.0 padding oracle.
Defense: Use authenticated encryption (GCM, CCM, ChaCha20-Poly1305). If CBC is unavoidable, use Encrypt-then-MAC and verify the MAC before attempting decryption — never reveal padding validity.
See also: crypto-lab-shadow-vault for ChaCha20-Poly1305 AEAD.
Self-check
Your CBC server reveals "bad padding" vs "bad MAC" via different error messages. How do you kill the oracle without rewriting the whole protocol?