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

Symmetric Encryption

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

Closest to 'specialist tool catches it' (d5). The detection_hints list semgrep and psalm as tools, with automated detection for patterns like openssl_encrypt without verifying the authentication tag, reusing nonces, or missing GCM authentication. These are specialist static analysis tools, not default linters or compiler errors — a developer must deliberately configure and run semgrep rules to catch ECB mode or IV reuse.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix points to swapping openssl_encrypt usage for sodium_crypto_secretbox, which handles nonce generation and authentication automatically. This is more than a one-liner because it involves replacing the encryption call, updating key management, and verifying ciphertext format — but it is contained within one component and does not require cross-cutting changes.

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

Closest to 'localised tax' (b3). The applies_to scope covers web, cli, and queue-worker contexts, giving it moderate reach. However, symmetric encryption is typically encapsulated in a single cryptographic utility or service layer rather than spread across the codebase. Once fixed (e.g., switching to Sodium), the burden does not persist as a broad productivity tax — it is a localised cryptographic implementation concern.

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

Closest to 'serious trap' (t7). The misconception field explicitly states that developers believe 'AES-256 in any mode is secure,' leading them to use ECB mode which silently leaks data patterns. This contradicts a reasonable expectation: if the algorithm name (AES-256) implies strength, the mode should not matter. This is a well-documented cryptographic gotcha that contradicts how developers reason about algorithm-level security — the obvious choice (AES-256-ECB) is silently dangerous.

About DEBT scoring →

Also Known As

AES AES-256-GCM ChaCha20 AEAD

TL;DR

Encryption where the same key encrypts and decrypts data — fast and suitable for bulk data, but key distribution is the primary challenge.

Explanation

Symmetric algorithms (AES, ChaCha20) use one key for both operations. AES-256-GCM is the current gold standard: 256-bit key, Galois/Counter Mode provides both encryption and authentication (AEAD). A unique random IV (nonce) must be used for every encryption with the same key. ChaCha20-Poly1305 is preferred on systems without AES hardware acceleration. The key distribution problem — securely sharing the key — is solved using asymmetric encryption or key exchange protocols.

Common Misconception

AES-256 in any mode is secure — AES-256-ECB (Electronic Codebook) encrypts identical blocks identically, leaking data patterns; always use GCM or another authenticated mode.

Why It Matters

Using the wrong cipher mode (ECB) or reusing an IV turns strong AES into weak or broken encryption — implementation choices matter as much as key length.

Common Mistakes

  • Using ECB mode — identical plaintext blocks produce identical ciphertext, revealing patterns.
  • Reusing the same IV with the same key — completely breaks GCM security.
  • Not using authenticated encryption (GCM) — unauthenticated ciphertext can be silently tampered with.
  • Storing the IV separately from the ciphertext in an unreliable way — prepend IV to ciphertext for simple management.

Code Examples

✗ Vulnerable
// AES-256-ECB — insecure mode, no authentication:
$encrypted = openssl_encrypt($data, 'AES-256-ECB', $key);
// Identical 16-byte blocks encrypt identically — patterns visible
// No IV — deterministic, dictionary-attackable
// No authentication — tampering undetectable
✓ Fixed
// AES-256-GCM — authenticated, random IV:
function encrypt(string $plaintext, string $key): string {
    $iv = random_bytes(12); // GCM standard IV size
    $tag = '';
    $ciphertext = openssl_encrypt(
        $plaintext, 'AES-256-GCM', $key,
        OPENSSL_RAW_DATA, $iv, $tag
    );
    return base64_encode($iv . $tag . $ciphertext); // IV + auth tag + ciphertext
}

function decrypt(string $encoded, string $key): string {
    $data = base64_decode($encoded);
    $iv = substr($data, 0, 12);
    $tag = substr($data, 12, 16);
    $ciphertext = substr($data, 28);
    return openssl_decrypt($ciphertext, 'AES-256-GCM', $key, OPENSSL_RAW_DATA, $iv, $tag);
}

Added 15 Mar 2026
Edited 22 Mar 2026
Views 68
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 1 ping W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 3 pings F 3 pings S 3 pings S 5 pings M 0 pings T 0 pings W 1 ping T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 1 ping S 3 pings S 1 ping M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Scrapy 13 Amazonbot 9 Perplexity 8 Google 4 Ahrefs 4 Bing 3 ChatGPT 3 Unknown AI 2 Claude 2 SEMrush 2 PetalBot 2 Meta AI 1
crawler 48 crawler_json 5
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Medium
⚡ Quick Fix
Use PHP's Sodium extension (sodium_crypto_secretbox) for authenticated symmetric encryption — it's simpler and safer than OpenSSL's AES-GCM because it handles nonce generation and authentication automatically
📦 Applies To
PHP 7.2+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
openssl_encrypt without verifying the authentication tag; reusing nonces; encryption without authentication (no GCM tag)
Auto-detectable: ✓ Yes semgrep psalm
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: Medium Context: Function Tests: Update
CWE-327 CWE-326


✓ schema.org compliant