Skip to content
Back to skills

Crypto Misuse

ASecurity

Block weak ciphers, predictable RNG, undersized keys, fast-hash password storage, nonce reuse, and non-constant-time comparison. Use when generating code that hashes, encrypts, or signs, code that compares secrets, MACs, or tokens, or config for key sizes and randomness.

  • 22 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 6, 2026
securityjavascriptpythongojavanodegitapisecurity

Works with

  • api

Security analysis

A100/100

Pro scans all 5 files and shows the line behind each finding

Scanned September 6, 2026

npx -y skills add ShieldNet-360/secure-vibe --skill crypto-misuse --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Crypto Misuse?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Crypto Misuse
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/shieldnet-360-crypto-misuse-98e3cae2/badge)](https://www.skillsdirectory.com/skills/shieldnet-360-crypto-misuse-98e3cae2)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
id: crypto-misuse
version: "1.1.0"
title: "Cryptographic Misuse"
description: "Block weak ciphers, predictable RNG, undersized keys, fast-hash password storage, nonce reuse, and non-constant-time comparison. Use when generating code that hashes, encrypts, or signs, code that compares secrets, MACs, or tokens, or config for key sizes and randomness."
category: prevention
severity: critical
applies_to:
  - "when generating code that hashes / encrypts / signs"
  - "when generating code that compares secrets / MACs / tokens"
  - "when choosing an algorithm, key size, or RNG"
languages: ["*"]
token_budget:
  minimal: 1700
  compact: 2300
  full: 3400
rules_path: "rules/"
related_skills: ["auth-security", "protocol-security", "secret-detection"]
last_updated: "2026-08-12"
sources:
  - "OWASP Password Storage Cheat Sheet"
  - "OWASP Cryptographic Storage Cheat Sheet"
  - "NIST SP 800-131A (current revision)"
  - "NIST SP 800-57 Part 1 (current revision)"
  - "CWE-327, CWE-338, CWE-916, CWE-208"
---

# Cryptographic Misuse

## Rules (for AI agents)

### ALWAYS
- Use a maintained, widely reviewed cryptographic API — the platform's own (Node
  `crypto`, Java JCE, .NET `System.Security.Cryptography`, Go `crypto/*`) or a
  reputable third-party one (PyCA `cryptography`, `golang.org/x/crypto`, Bouncy
  Castle). Prefer high-level, misuse-resistant APIs over assembling low-level
  primitives yourself. In Python, `from Crypto…` resolves to either the abandoned
  `pycrypto` or its maintained fork `pycryptodome` depending on what is installed —
  the import line is identical, so depend on `pycryptodome` explicitly.
- Use a cryptographically secure RNG for anything security-relevant: Python
  `secrets.token_bytes` / `secrets.token_urlsafe`, JS `crypto.getRandomValues` /
  `crypto.randomBytes`, Go `crypto/rand.Read`, Java `SecureRandom`.
- Hash passwords with a password-specific KDF and a unique random salt per password.
  Prefer Argon2id; scrypt where appropriate; bcrypt for legacy compatibility;
  PBKDF2-HMAC-SHA-256 where FIPS-140 compliance is required. Take minimum parameters
  from the current [OWASP Password Storage Cheat
  Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html),
  then benchmark on production hardware and choose the highest cost that still meets
  the application's authentication latency and availability budget. The cost is meant
  to be raised over time as hardware gets cheaper — it is not a constant to copy once.
- Account for bcrypt's 72-byte input limit: it silently truncates, so a long
  passphrase and its 72-byte prefix hash identically. If bcrypt must take unbounded
  input, pre-hash with SHA-256 and pass the digest **base64-encoded**, never as raw
  bytes — a raw digest can contain a NUL byte, which truncates the input again.
- Encrypt with a vetted AEAD: AES-GCM or ChaCha20-Poly1305, or AES-GCM-SIV where
  nonce-misuse resistance is specifically useful and the platform ships a reviewed
  implementation. Absent a stated key-size requirement, AES-256-GCM or
  ChaCha20-Poly1305 is a safe default — AES-128-GCM is not a finding.
- Follow the selected AEAD's nonce requirements. For AES-GCM and ChaCha20-Poly1305 the
  requirement is **uniqueness** under a given key, not randomness. A random 96-bit
  nonce is one strategy and carries a birthday bound; a counter-based nonce is often
  the stronger choice for high-volume encryption under one key. Do not assume
  nonce-misuse resistance unless the construction explicitly provides it.
- Compare MACs, authentication tokens, and other secret authenticators with the
  platform's constant-time helper: Python `hmac.compare_digest`, Node
  `crypto.timingSafeEqual`, Go `crypto/subtle.ConstantTimeCompare`, Java
  `MessageDigest.isEqual`, .NET `CryptographicOperations.FixedTimeEquals`. Node's
  helper throws when the buffers differ in length, so compare fixed-length digests
  rather than raw user input. For digital signatures, call the library's verification
  API instead of comparing signature bytes yourself. A constant-time comparison does
  not make the surrounding code constant-time.
- Select asymmetric algorithms and key sizes from current authoritative guidance
  rather than remembered constants. Prefer a modern platform-supported scheme
  (Ed25519, X25519, ECDSA P-256 or P-384); where RSA is required, enforce the current
  NIST SP 800-57 Part 1 minimum modulus. Key-size floors only move upward, so a
  remembered figure is one that has already expired.
- Obtain production keys from the platform's key-management boundary — see
  `secret-detection` for what counts as an embedded credential. What this skill owns
  is what comes after: version every key (carry a key id in the ciphertext envelope)
  so rotation does not strand data encrypted under the previous key, and derive
  per-purpose subkeys with a KDF instead of reusing one key across contexts.
- Consult `protocol-security` for anything on the wire — TLS versions and cipher
  suites, mTLS, certificate validation, gRPC channel credentials. It owns the
  transport; this skill owns the primitive.

### NEVER
- Use MD5 or SHA-1 for signatures, certificates, password storage, or message
  authentication.
- Use DES, 3DES, RC4, or Blowfish in new code.
- Use ECB mode. It leaks plaintext structure no matter how strong the key is.
- For a new design, assemble encryption yourself from an unauthenticated mode (CBC,
  CTR) plus a separately implemented MAC while a vetted AEAD is available.
- Store passwords with a fast hash (`sha256(password)`, MD5, SHA-1) or with a shared
  or fixed salt.
- Use JavaScript `Math.random()`, Python `random` (its `random.SystemRandom` is the
  exception), C `rand()`, or Go `math/rand` — `math/rand/v2` included — for tokens,
  IDs, nonces, keys, or passwords. Auto-seeding does not make a PRNG a CSPRNG.
- Hardcode a production key, or reuse a nonce / IV where the construction requires
  uniqueness. A protocol- or KDF-defined salt that is public by design (HKDF's `salt`
  parameter) is a different thing and may legitimately be fixed.
- Compare a MAC, secret token, password-derived value, or other secret authenticator
  using ordinary equality — `==`, `===`, `strcmp`, `bytes.Equal` — where an attacker
  can observe the timing and a constant-time API exists. Comparing two public values
  (a content hash, an ETag) with `==` is not a finding.
- 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 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 interoperability may genuinely require a deprecated primitive. Confine it to
  the specific protocol boundary, prevent downgrade outside that boundary, document
  the dependency and a removal plan, and never use the legacy primitive for newly
  designed storage or protocols. A feature flag is an operational mechanism, not the
  security control. Where a legacy CBC-plus-MAC construction survives, it must be
  Encrypt-then-MAC — MAC-then-Encrypt is what made Lucky13 possible.

## Context (for humans)

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). OWASP's storage and password-storage cheat sheets
are the practical companions to NIST's deprecation roadmap.

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 — but note the second failure mode it guards against:
rules that state a remembered constant as if it were permanent. Work factors, key-size
floors, and approved-algorithm lists all move. The rules above name where to look them
up rather than what they were on the day the rule was written.

## References

- `references/verifying-findings.md` — confirm or refute a finding, then lock it
- `rules/algorithm_blocklist.json`
- `rules/key_size_minimums.json`
- [OWASP Password Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html) — the source of record for KDF work factors.
- [OWASP Cryptographic Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html).
- [NIST SP 800-131A](https://csrc.nist.gov/publications/detail/sp/800-131a/rev-2/final) and [SP 800-57 Part 1](https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/final) — check the CSRC page for a newer revision before citing a minimum.
- [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.

Files in this skill

  • SKILL.md9 KB
  • references/verifying-findings.md4.7 KB
  • rules/algorithm_blocklist.json2.6 KB
  • rules/key_size_minimums.json1.4 KB
  • tests/corpus.json2.3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.