← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Block Cipher Modes

Cryptography PHP 7.1+ Advanced
debt(d5/e3/b3/t9)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5), because detection_hints lists semgrep and psalm as tools, and the code_pattern shows specific detectable patterns (ECB mode, CBC without HMAC, IV reuse) — these require configured specialist rules rather than a default linter or compiler, placing them squarely at d5.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3), because quick_fix says to swap to AES-256-GCM in one call to openssl_encrypt with different parameters. The fix is a mode replacement that may also require adding authentication handling (IV generation, tag verification), touching a small number of call sites within one component rather than a single-line swap or a cross-cutting refactor.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3), because applies_to scopes this to web and CLI contexts and the encryption choice is typically localised to a crypto/service layer. Once corrected to GCM, the rest of the codebase is unaffected; however the wrong choice does impose ongoing risk in that layer, slightly above b1 but not reaching b5 since it rarely bleeds into every work stream.

t9 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'catastrophic trap' (t9), because the misconception field states explicitly that 'AES is AES regardless of mode' — a competent developer who knows AES naturally assumes mode is a minor implementation detail, while in reality ECB leaks structure completely and IV reuse in GCM reveals both plaintexts. The 'obvious' choice (ECB or CBC) is always cryptographically wrong for structured data, matching the t9 anchor perfectly.

About DEBT scoring →

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.

Watch Out

Reusing the same nonce with GCM and the same key catastrophically breaks security — the authentication tag becomes predictable and ciphertext can be forged, even though GCM itself is otherwise correct. Always use a counter or random nonce generator; 'nonce' is not optional like an IV.

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

Added 16 Mar 2026
Edited 10 Jun 2026
Views 82
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
1 ping T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 2 pings W 0 pings T 2 pings F 3 pings S 3 pings S 5 pings M 0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 1 ping T 0 pings W 0 pings T 0 pings F 0 pings S 1 ping S 1 ping M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Amazonbot 19 Scrapy 13 Perplexity 8 Ahrefs 5 Unknown AI 4 SEMrush 4 Google 3 Claude 2 ChatGPT 2 PetalBot 2 Meta AI 1 Sogou 1
crawler 60 crawler_json 3 pre-tracking 1
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


✓ schema.org compliant