Tools · Cryptography and passwords in practice · 12 / 20
Why ECB mode is unsafe: seeing patterns leak through encrypted data
Encrypt the same data with ECB, CBC, and GCM, see repeated blocks survive ECB encryption, and learn which modes to choose and which to avoid.
Block cipher modes
AES encrypts 16-byte blocks. A mode decides how to handle longer messages. ECB encrypts each block independently with the same key, so identical plaintext blocks become identical ciphertext blocks. CBC chains each block with the previous ciphertext and needs a random IV. CTR and GCM turn AES into a stream; GCM adds authentication.
The pattern problem
The famous ECB penguin image shows the outline of a picture surviving encryption. You can reproduce the effect with text: a message with repeated 16-byte blocks shows repeated ciphertext blocks under ECB, and none under CBC or GCM.
import os
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
key = os.urandom(32)
block = b'ATTACK AT DAWN!!' # exactly 16 bytes
plain = block * 4
def blocks(b):
return [b[i:i + 16].hex()[:12] for i in range(0, len(b), 16)]
ecb = Cipher(algorithms.AES(key), modes.ECB()).encryptor()
print('ECB', blocks(ecb.update(plain) + ecb.finalize()))
cbc = Cipher(algorithms.AES(key), modes.CBC(os.urandom(16))).encryptor()
print('CBC', blocks(cbc.update(plain) + cbc.finalize()))
print('GCM', blocks(AESGCM(key).encrypt(os.urandom(12), plain, None)[:64]))Lab: run it and explain
Run the script and note that all four ECB blocks are identical, while CBC and GCM blocks differ. Then try an image: convert a simple bitmap with large flat areas to raw pixels, encrypt the pixel bytes with ECB and with CTR, keep the header, and view both. Write two sentences explaining why the ECB image is still recognizable.
# image experiment (requires ImageMagick and openssl) convert logo.png -depth 8 rgb:logo.rgb openssl enc -aes-128-ecb -K 00112233445566778899aabbccddeeff -nopad -in logo.rgb -out ecb.rgb openssl enc -aes-128-ctr -K 00112233445566778899aabbccddeeff -iv 000102030405060708090a0b0c0d0e0f -in logo.rgb -out ctr.rgb convert -size $(identify -format '%wx%h' logo.png) -depth 8 rgb:ecb.rgb ecb.png convert -size $(identify -format '%wx%h' logo.png) -depth 8 rgb:ctr.rgb ctr.png
What to use
Use an AEAD mode: AES-GCM or ChaCha20-Poly1305, through a high-level library. Avoid ECB entirely. Avoid unauthenticated CBC or CTR unless combined with a MAC in encrypt-then-MAC order, which high-level libraries already do for you. The fixed keys in the lab are for demonstration only.
Diagram
ECB versus GCM on repeated data
Same key, same plaintext.
Repeated blocks. Identical ciphertext blocks
Integrity. None
Use. Never for data
Repeated blocks. All different
Integrity. Authenticated with a tag
Use. Default choice with unique nonces
Check yourself
1. What is the core weakness of ECB?
2. Which mode is a good default?
3. Why is CBC without a MAC discouraged?