Skip to content
security

Anti-pattern: home-grown cryptography

Updated 2026-05-07

Cryptography is the canonical 'use a library, don't roll your own' domain. The home-grown antipattern routinely produces production-grade auth that has subtle, exploitable bugs the vendor library would have caught.

For the buy-vs-build framing at the platform level, see the build-vs-buy CIAM guide and the OAuth 2.1 explained guide.

Do

  • Use vetted libraries for password hashing, JWT signing, and encryption

    Cryptography has subtle implementation pitfalls (timing attacks, salt reuse, parameter mistakes). Vetted libraries (Argon2 reference, NaCl/libsodium, OpenSSL, browser SubtleCrypto) handle these correctly.

    OWASP Cryptographic Storage Cheat Sheet explicitly recommends vetted libraries. Multiple production CVEs have traced to custom crypto implementations introducing timing oracles, weak randomness, or salt reuse.

  • Use established standards (WebAuthn, OAuth 2.1, OIDC) for auth protocols

    Custom auth protocols don't get the security review that standards do. WebAuthn / OAuth / OIDC have specifications, conformance test suites, and decades of attack research.

    Documented production breaches at custom-protocol vendors. The standardized stack defeats entire attack classes by construction; custom protocols re-introduce the bugs the standards solved.

  • Adopt Argon2id for password hashing in new deployments

    Argon2id is the OWASP-recommended modern password hash, designed to resist GPU and ASIC attacks via memory-hard cost. Recommended parameters in 2026: m=64MB memory, t=3 iterations, p=1 parallelism.

    OWASP Password Storage Cheat Sheet and the Password Hashing Competition winner. Modern password libraries default to Argon2id; legacy bcrypt remains acceptable for existing hashes (re-hash on next login).

  • Defer to a vetted CIAM rather than building auth from scratch

    A modern CIAM ships the protocol implementations, the libraries, and the operational hardening. Building auth from scratch reintroduces all the bugs the CIAM market has already solved.

    CIAM vendor depth in this index, Auth0, Stytch, Clerk, Cognito, etc., covers protocols, hardening, and edge cases at a level that custom builds rarely match. The build-vs-buy guide covers when each makes sense.

Don't

  • Don't write custom JWT validation

    JWT validation has subtle algorithm-substitution, timing-attack, and parsing-edge-case vulnerabilities. Vetted libraries handle these; custom parsers don't.

    Multiple production CVEs at named vendors traced to hand-rolled JWT parsers. OWASP JWT Cheat Sheet recommends specific libraries (jose, PyJWT, jjwt, jsonwebtoken) and warns against custom implementations.

  • Don't implement password hashing yourself

    Argon2 / bcrypt / scrypt have specific parameter requirements, salt generation rules, and timing-attack mitigations. A 'simpler' custom implementation is the antipattern.

    Documented production breaches at vendors that hand-rolled password hashing. Vetted libraries exist for every language; using them is the floor.

  • Don't roll your own session token format

    Custom session token formats reintroduce signature, expiry, and replay-protection bugs the JWT / opaque-token literature has solved. Use the standard formats.

    Modern CIAM session models are JWT (signed) or opaque (server-side state). Custom tokens that try to be a third pattern routinely lack one or another security property, typically replay protection or revocability.

  • Don't use Math.random() or rand() for security-relevant randomness

    Standard random functions are not cryptographically secure. Use the platform's CSPRNG (crypto.randomBytes in Node, secrets module in Python, crypto.getRandomValues in browser).

    OWASP and broadly accepted security practice. Production CVEs have traced to predictable session tokens generated from non-CSPRNG sources.

Last updated 2026-05-07.