Cryptography for Developers
Apply cryptographic primitives correctly: hash passwords with bcrypt/Argon2, encrypt data with AES-GCM, sign JWTs, and configure TLS properly.
Cryptography is the foundation of data confidentiality, integrity, and authenticity. Most breaches stem from misuse-rolling your own crypto, using weak algorithms, or mismanaging keys-rather than flaws in the primitives themselves.
Never implement cryptographic algorithms from scratch. Use well-audited libraries. Follow the principle of using the highest-level abstraction available: prefer libsodium/NaCl APIs over raw AES, and JWT libraries over manual HMAC.
Workflow
- Hash passwords with a slow KDFbcrypt/Argon2 are intentionally slow, making brute-force attacks impractical even after a DB breach.
- Encrypt data at rest with AES-256-GCMGCM mode provides both confidentiality AND authenticity (AEAD), preventing tampering.
- Sign and verify data with asymmetric keysAsymmetric signatures prove authenticity without sharing a secret key.
- Configure TLS correctlyTLS 1.0/1.1 have known vulnerabilities; weak cipher suites enable downgrade attacks.
- Manage secrets and keys securelyKey exposure negates all cryptographic protections.
Output Format
Passwords hashed with Argon2id, sensitive data encrypted with AES-256-GCM+KMS, JWT signed with RS256/Ed25519, TLS 1.3 configured, key rotation documented.
Examples
Argon2id hash: `const hash = await argon2.hash(pw, { type: argon2.argon2id, memoryCost: 2**16, timeCost: 3, parallelism: 1 })`AES-GCM encrypt: `const iv = crypto.randomBytes(12); const cipher = crypto.createCipheriv("aes-256-gcm", key, iv); const enc = Buffer.concat([cipher.update(data), cipher.final()]); const tag = cipher.getAuthTag()`Ed25519 sign: `const sig = crypto.sign(null, Buffer.from(message), { key: privateKey, dsaEncoding: "der" })`Edge Cases & Gotchas
- Never reuse an IV/nonce with the same key in GCM mode-this breaks authenticity completely
- JWT "alg: none" attack: always explicitly verify algorithm type, reject "none"
- Timing attacks on string comparison: always use `crypto.timingSafeEqual()` for secret comparison
When to Break These Rules
- Use simpler symmetric encryption for non-sensitive internal data where performance is critical and integrity is enforced by other means (e.g., database transactions).
Reference Files
libsodium: https://libsodium.gitbook.io/OWASP Cryptographic Storage Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.htmlArgon2 spec: https://github.com/P-H-C/phc-winner-argon2