Cryptographic Misuse

SkillFiles & storage

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.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Cryptographic Misuse skill

What this skill tells your AI

The instructions your AI receives, as published by shieldnet-360/secure-vibe in skills/crypto-misuse/SKILL.md and read by ahel’s review.

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, 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/randmath/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

Signals

GitHub stars
22
Last commit
Aug 2026
Advanced
Catalog kind
skill
Gateway key
crypto-misuse
Source
github.com/shieldnet-360/secure-vibe