Algorithm selection justified against NIST
Why it matters
CWE-327 (use of a broken or risky cryptographic algorithm) is the direct consequence of algorithm selection without documented justification: teams inherit code using MD5 for hashing or AES-128 for encryption without realizing these are deprecated or insufficient for financial data contexts. NIST SP 800-131A defines algorithm transitions and deprecation timelines; NIST SC-13 requires approved cryptographic modules for protecting federal (and by extension, regulated financial) data. MD5 and SHA-1 are computationally broken for collision resistance; AES-128 is below the PCI-DSS 4.0 key strength floor for new implementations. Undocumented algorithm choices also block compliance auditors — a QSA cannot approve encryption that has no justification trail.
Severity rationale
High because undocumented or deprecated algorithm choices (MD5, SHA-1, AES-128 for new implementations) leave the system vulnerable to known cryptanalytic attacks and fail PCI-DSS QSA review.
Remediation
Create an algorithm selection document at docs/encryption-algorithms.md or in SECURITY.md that maps each use case to a NIST reference. Then verify the code matches:
// src/lib/crypto.ts — algorithm selection anchored to NIST
import crypto from 'node:crypto';
// AES-256-GCM — NIST SP 800-38D, provides authenticated encryption
const SYMMETRIC_ALGO = 'aes-256-gcm' as const;
// SHA-256 — NIST FIPS 180-4, used for HMAC only (not for passwords)
const HASH_ALGO = 'sha256' as const;
// Passwords: Argon2id — NIST SP 800-63B-4 recommends memory-hard KDFs
// Use the 'argon2' npm package — not crypto module
Replace any MD5 or SHA-1 usage immediately — they appear in older Node.js examples but are not acceptable for financial data under NIST SP 800-131A or PCI-DSS 4.0. The justification document must name the NIST publication, not just the algorithm name.
Detection
- ID:
nist-algorithm-justification - Severity:
high - What to look for: Enumerate all encryption algorithms used in the codebase and quote the actual algorithm identifier (e.g.,
aes-256-gcm,sha256,argon2id). Count every algorithm and classify as NIST-approved or deprecated. Look for documentation or comments explaining selection with NIST reference numbers. A deprecated algorithm (DES, MD5, SHA-1 for new protocols) must not pass — do not pass if any deprecated algorithm is used for new encryption. - Pass criteria: At least 90% of encryption algorithms are NIST-approved. At least 1 justification document or code comment references a NIST standard. Count all algorithms — report the ratio even on pass (e.g., "3 of 3 algorithms NIST-approved: AES-256-GCM (SP 800-38D), SHA-256 (FIPS 180-4), Argon2id").
- Fail criteria: Any non-NIST-approved or deprecated algorithm used for new encryption, OR no justification documented for algorithm selection.
- Skip (N/A) when: Encryption is entirely delegated to a managed service that guarantees NIST compliance — cite the actual service found.
- Detail on fail:
"1 of 3 algorithms is deprecated: MD5 used for hashing in src/utils/hash.ts — not NIST-approved"or"0 justification documents found for algorithm selection" - Cross-reference: Check
finserv-encryption.data-at-rest.aes256-encryptionfor at-rest algorithm verification, andfinserv-encryption.pci-alignment.encryption-documentationfor overall documentation. - Remediation:
- Document algorithm choices in a decision record or architecture document:
# Encryption Algorithm Selection - **Symmetric (at-rest):** AES-256-GCM - Justification: NIST SP 800-38D approved, 256-bit key provides quantum resistance margin - Alternative rejected: AES-128 (shorter key period) - **Symmetric (in-transit):** TLS 1.3 (TLS_AES_256_GCM_SHA384) - Justification: NIST-approved, modern cipher suite - **Hashing:** SHA-256 - Justification: NIST FIPS 180-4 approved - Use NIST-approved algorithms in code:
import crypto from 'crypto'; // AES-256-GCM (NIST-approved) const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
- Document algorithm choices in a decision record or architecture document:
External references
- cwe · CWE-327 — Use of a Broken or Risky Cryptographic Algorithm
- owasp:2021 · A02 — Cryptographic Failures
- nist:rev5 · SC-13 — Cryptographic Protection
- nist:rev2 · SP-800-131A — Transitioning the Use of Cryptographic Algorithms and Key Lengths
- nist:final · SP-800-38D — Recommendation for Block Cipher Modes of Operation: GCM and GMAC
Taxons
History
- 2026-04-18·v1.0.0·Initial import from finserv-encryption·automated