Skip to main content

Free 30-min security demo  — We'll scan your real code and show live findings, no commitment Book Now

Offensive360
Academy ECB Mode Encryption
Intermediate · 20 min

ECB Mode Encryption

See why ECB mode leaks patterns in encrypted data and why CBC and GCM modes with random IVs are essential.

1 ECB's Fatal Flaw: Pattern Leakage

Electronic Codebook (ECB) mode encrypts each block of plaintext independently with the same key. This means identical plaintext blocks always produce identical ciphertext blocks — leaking structure even without decrypting.

ECB encryption (vulnerable):

from Crypto.Cipher import AES

cipher = AES.new(key, AES.MODE_ECB)  # NEVER use ECB!
ciphertext = cipher.encrypt(pad(data, 16))

The classic demonstration is encrypting a bitmap image with ECB — the encrypted image still reveals the outlines of the original, because identical pixel blocks produce identical ciphertext blocks.

Practical attack scenario:

Consider an API that encrypts user role tokens in ECB mode. If an attacker discovers that a block at position N corresponds to "role=admin", they can copy that block from an admin token they observe into their own token at the same position.

ECB also enables cut-and-paste attacks: rearranging ciphertext blocks to rearrange plaintext blocks without knowing the key.

2 Use CBC or GCM with Random IV

CBC (Cipher Block Chaining) XORs each plaintext block with the previous ciphertext block before encrypting. GCM (Galois/Counter Mode) adds authentication. Both require a random Initialization Vector (IV) to ensure identical plaintexts produce different ciphertexts.

AES-GCM (recommended — authenticated encryption):

from Crypto.Cipher import AES
import os

def encrypt(key, plaintext):
    iv = os.urandom(12)  # 96-bit random nonce for GCM
    cipher = AES.new(key, AES.MODE_GCM, nonce=iv)
    ciphertext, tag = cipher.encrypt_and_digest(plaintext.encode())
    return iv + tag + ciphertext  # Prepend IV and auth tag

def decrypt(key, data):
    iv, tag, ciphertext = data[:12], data[12:28], data[28:]
    cipher = AES.new(key, AES.MODE_GCM, nonce=iv)
    return cipher.decrypt_and_verify(ciphertext, tag).decode()

Why GCM over CBC: GCM provides authenticated encryption — the auth tag detects tampering. CBC alone does not authenticate, enabling padding oracle attacks.

Defense checklist:

  • Never use AES-ECB mode
  • Use AES-GCM for authenticated encryption
  • Always generate a fresh random IV/nonce per encryption
  • Never reuse an IV with the same key

Knowledge Check

0/3 correct
Q1

Why does ECB mode leak information about plaintext structure?

Q2

What is the purpose of the IV (Initialization Vector) in CBC mode?

Q3

What advantage does AES-GCM have over AES-CBC?

Code Exercise

Replace ECB with AES-GCM

The code uses AES in ECB mode, which leaks plaintext patterns. Replace it with AES-GCM using a random 12-byte nonce.

python