---
id: crypto-misuse
version: "1.0.0"
title: "Cryptographic Misuse"
description: "Block weak ciphers, predictable RNG, undersized keys, slow-hash misuse, and non-constant-time comparisons"
category: prevention
severity: critical
applies_to:
  - "when generating code that hashes / encrypts / signs"
  - "when generating code that compares secrets / MACs / tokens"
  - "when wiring TLS settings, key sizes, or RNG"
languages: ["*"]
token_budget:
  minimal: 1000
  compact: 1200
  full: 2500
rules_path: "rules/"
related_skills: ["secret-detection", "auth-security", "protocol-security"]
last_updated: "2026-05-13"
sources:
  - "NIST SP 800-131A Rev. 2"
  - "NIST SP 800-57 Part 1 Rev. 5"
  - "OWASP Cryptographic Storage Cheat Sheet"
  - "CWE-327, CWE-338, CWE-916, CWE-208"
---

# Cryptographic Misuse

## Rules (for AI agents)

### ALWAYS
- Use the language / platform's cryptographic library. Python: `cryptography`,
  `secrets`. JavaScript: Web Crypto, `crypto.webcrypto`, Node `crypto`. Go:
  `crypto/*`, `golang.org/x/crypto`. Java: JCE/Bouncy Castle. .NET:
  `System.Security.Cryptography`.
- Use a cryptographically secure RNG: Python `secrets.token_bytes` /
  `secrets.token_urlsafe`, JS `crypto.getRandomValues` / `crypto.randomBytes`,
  Go `crypto/rand.Read`, Java `SecureRandom`.
- Hash passwords with a slow KDF tuned for ~100 ms on production hardware:
  **argon2id** (preferred, RFC 9106 parameters: m=64 MiB, t=3, p=1), **scrypt**
  (N=2^17, r=8, p=1), or **bcrypt** (cost ≥ 12). Always with a per-user random
  salt.
- Encrypt with AEAD (authenticated encryption): AES-256-GCM, ChaCha20-Poly1305,
  or AES-256-GCM-SIV. Generate a fresh random nonce per encryption.
- Use TLS 1.2+ (TLS 1.3 strongly preferred). Disable TLS 1.0/1.1, SSLv3,
  RC4, 3DES, and export ciphers.
- Compare MACs / signatures / tokens with constant-time helpers:
  `hmac.compare_digest`, `crypto.subtle.timingSafeEqual`,
  `subtle.ConstantTimeCompare`, `MessageDigest.isEqual`,
  `CryptographicOperations.FixedTimeEquals`.
- For asymmetric keys: RSA ≥ 3072 bits, ECDSA P-256 or P-384, Ed25519, X25519.

### NEVER
- Use MD5 or SHA-1 for signatures, certificates, password storage, or message
  authentication. (They remain valid for incidental non-security uses like
  ETag / file deduplication if explicitly documented.)
- Use DES, 3DES, RC4, or Blowfish for new code.
- Use ECB mode. Use CBC without HMAC over the ciphertext. Use CTR/GCM with a
  reused nonce.
- Use unsalted hashes for passwords. Use `sha256(password)` for password
  storage — it's a fast hash; brute force is trivial.
- Use `Math.random()`, Python `random`, `rand()` in C / Go for tokens, IDs,
  nonces, or passwords. They are predictable.
- Hardcode IVs/nonces, salts, or keys. Never reuse a GCM/Poly1305 nonce under
  the same key.
- Compare secrets with `==`, `===`, `strcmp`, `bytes.Equal` — these are
  timing-leaky.
- Roll your own crypto (custom XOR, custom HMAC, custom Diffie–Hellman, custom
  signature schemes). Use audited primitives.

### KNOWN FALSE POSITIVES
- MD5 / SHA-1 in non-security contexts: HTTP ETag computation, content
  deduplication, cache keying for non-sensitive data, fixture fingerprinting.
  Annotate these uses with a `// non-security use: ...` comment.
- Test vectors and KAT (Known Answer Test) values intentionally hardcode IVs,
  keys, and plaintexts — they belong in `tests/` not production.
- Legacy interop: some industry / government protocols still require specific
  legacy ciphers. Document the exception and isolate behind a feature flag.

## Context (for humans)

NIST SP 800-131A Rev. 2 is the authoritative US-government deprecation roadmap
for algorithms; OWASP's storage cheat sheet is the practical "do these things"
companion. The recurring failure modes are: fast hash for passwords (CWE-916),
predictable RNG for tokens (CWE-338), broken cipher choice (CWE-327), and
non-constant-time comparison of secrets (CWE-208).

AI assistants tend to mirror whatever crypto example was popular on Stack
Overflow circa 2014, which means lots of `sha256(password)` and `AES-CBC` with
manual padding. This skill is the counterweight.

## References

- `rules/algorithm_blocklist.json`
- `rules/key_size_minimums.json`
- [NIST SP 800-131A Rev. 2](https://csrc.nist.gov/publications/detail/sp/800-131a/rev-2/final).
- [OWASP Cryptographic Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html).
- [CWE-327](https://cwe.mitre.org/data/definitions/327.html) — Broken or risky crypto.
- [CWE-916](https://cwe.mitre.org/data/definitions/916.html) — Insufficient computational effort for password hash.
