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.
Scanned 9/6/2026
Install to Claude Code
npx -y skills add ShieldNet-360/secure-vibe --skill crypto-misuse --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Crypto Misuse?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/shieldnet-360-crypto-misuse-secure-vibe)More formats (shields.io, HTML) on the badges page.
---
name: crypto-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."
---
<!-- Native skill bundle for Claude Code. Generated by `secure-vibe dev regenerate`. -->
<!-- Do not edit by hand; the source of truth is skills/crypto-misuse/SKILL.md. -->
# Cryptographic Misuse
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.
## 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.
## Reference files
Read these only when the task calls for them.
- `references/verifying-findings.md`
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!