# Algorithm selection justified against NIST

- **Pattern:** `ab-001426` (`finserv-encryption.key-management.nist-algorithm-justification`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001426
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001426)

## 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:

```typescript
// 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-encryption` for at-rest algorithm verification, and `finserv-encryption.pci-alignment.encryption-documentation` for overall documentation.
- **Remediation:**
  - Document algorithm choices in a decision record or architecture document:
    ```markdown
    # 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:
    ```typescript
    import crypto from 'crypto';
    // AES-256-GCM (NIST-approved)
    const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
    ```

## External references

- cwe CWE-327
- owasp A02
- nist SC-13
- nist SP-800-131A
- nist SP-800-38D

Taxons: cryptography-and-secrets, regulatory-conformance

HTML version: https://auditbuffet.com/patterns/ab-001426
