Most real-world cryptographic failures come from using sound algorithms in unsound ways, not from someone breaking AES. Cryptographic misuse means choosing a broken or risky algorithm, using a strong one with the wrong mode, nonce, key or randomness, or combining correct pieces into a protocol that leaks through errors, timing or negotiation. The history of TLS is a catalogue of these failures, from padding oracles to downgrade attacks, and the same patterns reappear in application code every year. This explainer sets out the main failure classes in plain terms, then gives code reviewers and security engineers the specifics to spot them: the CWE entries, the review questions and the safer defaults. It goes deeper on mechanisms than the OWASP Top 10 A04 Guide, which covers the category as a whole.
Key takeaways
- Misuse beats cryptanalysis. Padding oracles, nonce reuse, weak randomness and downgrade attacks break systems built on algorithms that remain mathematically strong.
- Authenticated encryption removes whole attack classes. AES-GCM or ChaCha20-Poly1305 through a maintained library avoids the MAC-then-encrypt designs that made padding oracles possible.
- Nonces and IVs are part of the key. Reusing a nonce with the same key in a counter-based mode such as GCM can expose plaintext relationships and allow forgeries.
- Negotiation is an attack surface. Any protocol that lets the peer choose algorithms or versions must protect that choice, or attackers will choose the weakest option for you.
- Security randomness must come from a CSPRNG. Statistical generators such as
Math.random()orjava.util.Randomare predictable and must never produce keys, tokens or IVs.
What it is
Cryptographic misuse is any use of cryptography that fails to deliver the confidentiality, integrity or authenticity the designer intended, even though the underlying primitive is not broken. MITRE's Common Weakness Enumeration captures the main families:
| CWE | Name | Typical example in code |
|---|---|---|
| CWE-327 | Use of a Broken or Risky Cryptographic Algorithm | DES, RC4, MD5 or SHA-1 for integrity; ECB mode; homegrown ciphers |
| CWE-328 | Use of Weak Hash | MD5 for file integrity or signatures |
| CWE-780 | Use of RSA Algorithm without OAEP | RSA encryption with PKCS#1 v1.5 padding or no padding |
| CWE-916 | Use of Password Hash With Insufficient Computational Effort | Fast unsalted hashes for stored passwords |
| CWE-330 | Use of Insufficiently Random Values | Session tokens from a statistical PRNG |
| CWE-338 | Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG) | Math.random() for reset tokens |
| CWE-1204 | Generation of Weak Initialization Vector (IV) | Fixed or predictable CBC IVs |
| CWE-323 | Reusing a Nonce, Key Pair in Encryption | Constant GCM nonce, or a counter reset on restart |
| CWE-208 | Observable Timing Discrepancy | Comparing MACs or tokens with an early-exit string compare |
CWE-327 sits under CWE-693 Protection Mechanism Failure, and its mitigations are short and practical: use well-vetted algorithms and implementations, avoid custom cryptography, review algorithm choices periodically, design for replacement and protect keys, because algorithm strength is irrelevant if the key is guessed or stolen.
How it works
Padding and error oracles
An oracle exists when a system reveals, through an error message, a status code or a timing difference, whether a submitted ciphertext decrypted "correctly". RFC 7457 traces TLS padding oracles to MAC-then-encrypt: the receiver decrypts, checks padding, then checks the MAC, and the different failure paths leak information. Lucky Thirteen (CVE-2013-0169) was a timing variant; POODLE (CVE-2014-3566) targeted SSL 3.0, for which RFC 7457 records no known mitigation other than not using it. The RSA equivalent is Bleichenbacher's attack on PKCS#1 v1.5 encryption padding, which RFC 7457 also lists. The same pattern appears in applications that decrypt a CBC-encrypted cookie or token and return "invalid padding" separately from "invalid token".
Reviewer cue: unauthenticated CBC, decrypt before verify, distinct errors for padding and integrity failures, RSA PKCS#1 v1.5 encryption.
Nonce and IV reuse
Counter-based modes such as CTR and GCM turn a key and nonce into a keystream. Encrypting two messages with the same key and nonce produces the same keystream, so an attacker learns the XOR of the plaintexts; in GCM, reuse also undermines the authentication tag and can allow forgeries. CBC needs unpredictable IVs: BEAST (CVE-2011-3389) exploited the predictable IVs of TLS 1.0 CBC to recover cookie contents. Nonce reuse usually comes from a constant written into code, a counter that resets on restart, random 96-bit nonces used beyond safe message counts, or several instances sharing one key without coordination. The OWASP Cryptographic Storage Cheat Sheet treats IV uniqueness across all instances sharing a key as a usage limit to enforce during rotation.
Reviewer cue: literal IV or nonce values, IVs derived from timestamps or record IDs, a single key shared by many writers, no rotation tied to message counts.
Downgrade and negotiation attacks
When two parties negotiate a protocol version or cipher suite, an active attacker may try to force the weakest mutually supported choice. RFC 7507 (April 2015) describes the classic case: clients that retried failed TLS handshakes at lower versions could be pushed down to SSL 3.0. Its TLS_FALLBACK_SCSV signal lets a server detect an inappropriate fallback and abort with the fatal inappropriate_fallback alert. Other negotiation failures in RFC 7457 include SSL stripping (removing TLS entirely from HTTP, mitigated by HSTS) and STARTTLS command injection (CVE-2011-0411). The general weakness is CWE-757, Selection of Less-Secure Algorithm During Negotiation. In application protocols, the equivalent is a token format that lets the sender choose the verification algorithm, which is why JSON Web Token guidance requires the verifier to enforce an expected algorithm.
Reviewer cue: legacy versions still enabled "for compatibility", algorithm taken from the message header, fallback logic that retries with weaker settings.
Weak randomness
CWE-330 explains that statistical PRNGs are predictable and unsuitable wherever security depends on unpredictable values. Keys, IVs, session IDs, CSRF tokens and password reset tokens all need a CSPRNG: SecureRandom in Java, secrets in Python, crypto.randomBytes() in Node.js, crypto/rand in Go, getrandom(2) in C, RandomNumberGenerator in .NET and random_bytes() in PHP, as listed by OWASP. UUIDs are not a substitute: version 1 UUIDs are not random, and version 4 is only as good as the generator behind it.
Composition and side-channel failures
- Compression before encryption: CRIME (CVE-2012-4929) used TLS compression, and TIME and BREACH used HTTP compression, to recover secrets from the length of encrypted responses. Disabling TLS compression fixes CRIME; BREACH needs application-level measures such as not reflecting user input next to secrets.
- Weak key exchange parameters: RFC 7457 notes cross-protocol attacks on ephemeral Diffie-Hellman parameters and recommends predefined groups.
- Renegotiation and channel binding: the renegotiation flaw (CVE-2009-3555, fixed by RFC 5746) and the triple handshake attack (CVE-2014-1295) show that individually correct handshakes can combine into an insecure whole.
- Timing: non-constant-time comparison of MACs, tokens or password hashes leaks how many leading bytes match (CWE-208).
Why it matters
These failures turn encryption into a false sense of safety. Data that is "encrypted" with a reused nonce or an oracle-prone mode can be read or modified; tokens from a weak generator can be predicted; a protocol with an unprotected negotiation is only as strong as its weakest enabled option. Because the code works and the tests pass, misuse usually survives until someone looks specifically for it.
| Failure class | What an attacker gains | Safer default |
|---|---|---|
| Padding or error oracle | Decryption of ciphertexts, sometimes forgery | Authenticated encryption (AES-GCM, ChaCha20-Poly1305); RSA-OAEP or, better, a hybrid scheme such as HPKE; uniform errors |
| Nonce or IV reuse | Plaintext relationships, tag forgery in GCM | Library-managed nonces, per-instance keys, rotation before usage limits; misuse-resistant modes such as AES-GCM-SIV where reuse risk is high |
| Downgrade | Forces the weakest enabled algorithm or version | Disable legacy versions and suites; protect negotiation; fix the verification algorithm server-side |
| Weak randomness | Predicted keys, tokens and IDs | Platform CSPRNG only |
| Broken algorithm | Collisions (MD5, SHA-1), brute force (DES), keystream bias (RC4) | AES with 128-bit or 256-bit keys, SHA-2 or SHA-3, current guidance from NIST and national agencies |
| Timing leaks | Byte-by-byte recovery of secrets | Constant-time comparison functions from the crypto library |
For non-human identities the stakes are concrete: API tokens, signed webhooks, session cookies for service accounts and encrypted secrets in configuration all rely on these primitives. A predictable token generator or an unauthenticated encrypted cookie is a machine credential an attacker can mint. See the Cryptographic Key Management Guide for the key side of the problem.
Common misconceptions
- "AES is secure, so our encryption is secure": AES in ECB mode leaks patterns, AES-CBC without a MAC can be an oracle, and AES-GCM with a repeated nonce fails badly. The mode, nonce and key handling matter as much as the cipher.
- "Encryption gives integrity": unauthenticated encryption lets attackers flip bits or splice ciphertexts. Only authenticated encryption or a separate MAC, applied encrypt-then-MAC, gives integrity.
- "Hashing is encryption" or "a hash is a MAC": a plain hash of secret plus data is not a sound MAC construction; use HMAC or the AEAD tag.
- "Leaving old protocol versions enabled is harmless if clients prefer new ones": downgrade attacks exist precisely because attackers can interfere with that preference.
- "Random is random": the default random function in most languages is designed for simulations, not security.
- "We wrote our own because the library was too complex": CWE-327 mitigations are blunt about custom cryptography, and OWASP's advice is simply not to do it.
Related concepts
- Authenticated encryption with associated data (AEAD): modes such as GCM and CCM, specified for AES in NIST SP 800-38D (GCM) and SP 800-38C (CCM). NIST announced in 2024 that it will revise SP 800-38D. See the Authenticated Encryption and Cipher Modes Guide.
- Key exchange: where negotiation and parameter validation failures live. See the Key Exchange and Diffie-Hellman Guide.
- TLS configuration: disabling legacy versions and suites removes most historic TLS attacks. See the TLS Server Configuration Baseline Guide.
- Crypto-agility: CWE-327 recommends wrappers and uniform interfaces so algorithms can be replaced, which is the core of agility and post-quantum migration. See the Crypto-Agility Guide.
- Validated modules: using FIPS 140-3 validated modules avoids many entropy and implementation errors. See the FIPS 140-3 Cryptographic Module Validation Guide.
Mapping to verification standards
OWASP ASVS 5.0 chapter V11 Cryptography turns most of this page into testable requirements, and NIST SP 800-53 Rev. 5 SC-13 Cryptographic Protection is the parent control for algorithm choice.
| Failure class | OWASP ASVS 5.0 | CWE |
|---|---|---|
| Weak modes and padding | V11.3.1 (no ECB, no weak padding such as PKCS#1 v1.5); V11.3.2 (approved ciphers and modes such as AES-GCM) | CWE-327, CWE-780 |
| Missing integrity | V11.3.3 (encrypted data protected against unauthorised modification); V11.3.5 (encrypt-then-MAC when combining cipher and MAC) | CWE-327 |
| Nonce and IV reuse | V11.3.4 (single-use numbers not reused for more than one key and data-element pair) | CWE-323, CWE-1204 |
| Weak randomness | V11.5.1 (non-guessable values from a CSPRNG); V11.5.2 (generator works securely under heavy demand) | CWE-330, CWE-338 |
| Timing and error leaks | V11.2.4 (constant-time operations); V11.2.5 (modules fail securely) | CWE-208 |
| Weak hashes | V11.4.1 (approved hash functions); V11.4.2 (computationally intensive password hashing) | CWE-328, CWE-916 |
| Replaceability | V11.2.2 (crypto agility) | CWE-327 mitigation |
Practitioner checklist
- Search code for broken algorithms and modes: DES, 3DES, RC4, MD5 and SHA-1 for integrity, ECB, unauthenticated CBC, RSA without OAEP.
- Require AEAD through a maintained high-level library for new encryption, and let the library generate nonces.
- Check every encryption key for how many writers share it and how nonce uniqueness is guaranteed across restarts and instances.
- Replace non-cryptographic random functions in any security context with the platform CSPRNG.
- Make decryption and verification failures return one generic error, and verify integrity before acting on decrypted data.
- Use constant-time comparison for MACs, tokens and hashes.
- Disable legacy TLS versions and suites, and never let a message choose its own verification algorithm.
- Add crypto misuse rules to static analysis and to the code review checklist, and track findings by CWE.
Standards and references
- MITRE CWE: CWE-327 Use of a Broken or Risky Cryptographic Algorithm
- MITRE CWE: CWE-330 Use of Insufficiently Random Values
- MITRE CWE: CWE-323 Reusing a Nonce, Key Pair in Encryption
- IETF: RFC 7457 Summarizing Known Attacks on TLS and DTLS
- IETF: RFC 7507 TLS Fallback SCSV for Preventing Protocol Downgrade Attacks
- NIST: SP 800-38D Galois/Counter Mode (GCM) and GMAC
- OWASP: Application Security Verification Standard 5.0
- OWASP: Cryptographic Storage Cheat Sheet
Related NHI Mgmt Group resources: OWASP Top 10 A04 Guide · Cryptography Basics Guide · Cryptographic Key Management Guide · Crypto-Agility Guide