Block Cipher Modes
Also Known As
ECB
CBC
GCM
CTR
AEAD
cipher mode
TL;DR
How a block cipher (AES) processes data larger than one block — ECB is insecure, CBC requires a MAC, GCM provides authenticated encryption and is the correct choice.
Explanation
Block ciphers encrypt fixed-size blocks. Modes define how blocks relate: ECB (each block encrypted independently — identical plaintext blocks produce identical ciphertext, leaking patterns), CBC (each block XORed with previous ciphertext — requires padding and a separate MAC for integrity), CTR (turns block cipher into stream cipher — no padding, but no authentication), GCM (CTR mode + GHASH authentication — authenticated encryption, no separate MAC needed, parallelisable). AES-256-GCM is the correct choice for new implementations. Nonces/IVs must be unique per encryption.
Common Misconception
✗ AES is AES regardless of mode — AES-ECB is trivially broken for any structured data; the mode determines security properties as much as the key length.
Why It Matters
AES-ECB encrypted images still show the original image's patterns (the infamous penguin attack) — choosing the wrong mode nullifies the protection of a strong cipher.
Common Mistakes
- AES-ECB for any structured data — identical 16-byte blocks produce identical ciphertext, leaking structure.
- CBC without MAC (encrypt-then-MAC) — CBC is malleable; an attacker can modify ciphertext without detection.
- Reusing an IV with the same key in GCM — catastrophic; two ciphertexts XOR to reveal both plaintexts.
- Not authenticating the associated data in GCM — headers/metadata can be tampered without invalidating the tag.
Code Examples
✗ Vulnerable
// AES-ECB — insecure:
$encrypted = openssl_encrypt($data, 'AES-256-ECB', $key);
// Identical 16-byte blocks encrypt identically
// 'aaaaaaaaaaaaaaaa' encrypts to the same ciphertext every time
// CBC without authentication:
$iv = random_bytes(16);
$encrypted = openssl_encrypt($data, 'AES-256-CBC', $key, 0, $iv);
// No MAC — ciphertext can be silently tampered
✓ Fixed
// AES-256-GCM — authenticated encryption:
$iv = random_bytes(12); // 96-bit nonce for GCM
$tag = '';
$ciphertext = openssl_encrypt(
$data, 'AES-256-GCM', $key, OPENSSL_RAW_DATA, $iv, $tag,
$additionalData // Authenticated but not encrypted (e.g. sender ID)
);
$stored = base64_encode($iv . $tag . $ciphertext);
// Decryption verifies tag automatically — tampered data rejected
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
16 Mar 2026
Edited
22 Mar 2026
Views
39
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
No pings yesterday
Amazonbot 16
Perplexity 8
Unknown AI 4
Ahrefs 3
Google 2
SEMrush 1
Also referenced
How they use it
crawler 33
pre-tracking 1
Related categories
⚡
DEV INTEL
Tools & Severity
🟠 High
⚙ Fix effort: Medium
⚡ Quick Fix
Use AES-256-GCM — it provides authenticated encryption (confidentiality + integrity) in one operation; never use ECB mode (no IV, patterns visible) or CBC without HMAC
📦 Applies To
PHP 7.1+
web
cli
🔗 Prerequisites
🔍 Detection Hints
openssl_encrypt with 'AES-256-CBC' without HMAC authentication; 'AES-256-ECB' mode; using same IV twice; storing IV with encrypted data in same field
Auto-detectable:
✓ Yes
semgrep
psalm
⚠ Related Problems
🤖 AI Agent
Confidence: High
False Positives: Low
✓ Auto-fixable
Fix: Low
Context: Function
Tests: Update
CWE-327
CWE-326