Most cryptographic failures aren't broken algorithms — they're misuse. Here are the mistakes you'll actually encounter.
Custom encryption schemes are nearly always broken. Use vetted libraries.
API keys and private keys in source code or Git history are a leading breach cause.
1# Scan your repo and history for secrets
2git log -p | grep -i "api_key\|secret\|password" # quick smell test
3# Better: use automated scanners (gitleaks, trufflehog) in CIIf a secret is ever committed, rotate it — removing it from history isn't enough; assume it's compromised.
Using Math.random() or a predictable seed for keys, tokens, or IVs. Always use a cryptographically secure RNG (crypto.randomBytes, /dev/urandom, secrets module).
In modes like AES-GCM, reusing a nonce with the same key is catastrophic — it can leak the key stream. Generate a fresh random nonce per message.
Encrypts identical plaintext blocks to identical ciphertext — patterns leak. Use authenticated modes (GCM, ChaCha20-Poly1305).
Encryption alone doesn't prevent tampering. Use authenticated encryption (AEAD) so modified ciphertext is rejected.
| State | Protection |
|---|---|
| In transit | TLS 1.3 |
| At rest | Disk/database encryption (AES-256), KMS-managed keys |
| In use | Hardest; emerging confidential-computing / enclaves |
The hardest part of crypto isn't encrypting — it's managing keys: