Most codebases reach for SHA-256 by default — sometimes correctly, sometimes not. A decision-first guide to MD5, SHA-1, SHA-2, SHA-3, and BLAKE3, plus the one category where all of them are the wrong answer.
Every time someone opens a Stack Overflow thread asking "which hash should I use?", the top answer is SHA-256. Sometimes that's right. Sometimes it's desperately wrong — like when the question is about passwords, where SHA-256 will get you pwned within seconds of a database dump. The answer depends on what you're hashing and why, and the five-second "just use SHA-256" advice skips the part that actually matters.
This is a decision-first tour of the hash functions you'll actually encounter: why some are broken, where the line between "safe" and "unsafe" context actually falls, and why faster isn't always better.
MD5: retired, not quite dead
MD5 is everywhere. npm has historically used it for package integrity. Legacy database systems lean on it for deduplication. Build caches, CDN ETags, and file-transfer verification scripts from the early 2000s are full of it. For those non-security uses — did this 50 GB file transfer without bit-rot? — MD5 is still fine. Fast, universally implemented, 128-bit output that's trivial to store and compare.
For anything where collision resistance matters — code signing, certificate fingerprints, digital signatures, any authentication context — MD5 has been broken since 2004, when Xiaoyun Wang's team demonstrated practical collisions in under an hour on a cluster. By 2008, researchers had used MD5 collisions to forge a rogue CA certificate that browsers trusted. That's not a theoretical risk. That's a worked example.
The distinction is: MD5 is fine for corruption detection (did this file arrive intact?) and useless for tamper detection (did someone modify this file while pretending not to?). Use it for the former only if you inherited the system. Don't start new code with it.
SHA-1: SHAttered
SHA-1 outlived MD5's collision resistance by about a decade before the SHAttered attack (2017, CWI Amsterdam and Google) produced two different PDFs with an identical SHA-1 hash — at a cost of roughly $110,000 in cloud compute. Within a couple of years, the same class of attack became cheaper. Browser vendors had already dropped SHA-1 TLS certificate support in 2017. Git still uses SHA-1 as the default object identifier in older repositories, but that's an identifier, not a security primitive, and new Git repos can opt into SHA-256 mode since 2020.
Same verdict as MD5: fine for legacy non-security checksums, broken everywhere else. Don't authenticate, sign, or verify with it.
SHA-256 and SHA-512: the sensible defaults
SHA-2 — which covers SHA-224, SHA-256, SHA-384, and SHA-512 — is the NIST standard (FIPS 180-4) and what you should reach for when you need a general-purpose cryptographic hash. SHA-256 has 256-bit output, 128-bit collision resistance, and no known weaknesses worth worrying about. It's hardware-accelerated on any x86 CPU with SHA-NI extensions (2016+) and on Apple silicon.
Use SHA-256 for HMAC signatures (HMAC-SHA256 is what most JWTs use — if you're decoding or verifying a token, our JWT decoder will show you the algorithm in the header), file integrity verification in software distribution, content-addressed storage, and message digests in TLS and code signing.
SHA-512 uses 64-bit word operations, which means it's slower on 32-bit hardware but marginally faster than SHA-256 on 64-bit systems for large inputs. Use it when you want more output material — deriving multiple keys from one hash, or extra margin in long-lived signatures where you'd rather not revisit the choice in five years.
NIST FIPS 180-4, the authoritative specification for the SHA-2 family, puts the security goal plainly:
"The hash algorithms specified in this Standard are called secure because, for a given algorithm, it is computationally infeasible to find a message that corresponds to a given message digest, or to find two different messages that produce the same message digest."
— NIST FIPS 180-4 (U.S. federal government work, public domain)
That phrase "computationally infeasible" is load-bearing. SHA-256 satisfies it today. MD5 and SHA-1 don't.
SHA-3: the structural backup
SHA-3 (FIPS 202, standardized 2015) is not SHA-2's successor — it's a deliberate alternative. It uses a completely different internal construction (the Keccak sponge) rather than SHA-2's Merkle-Damgård structure. NIST standardized it specifically so that if SHA-2 turned out to have a structural flaw, there'd be a fallback with different failure modes. SHA-2 has had no such flaw, so SHA-3 hasn't displaced it.
SHA-3 isn't faster than SHA-256 in software — SHA-256 wins on most general-purpose CPUs, especially with SHA-NI. Use SHA-3 when you want defense in depth against SHA-2 weaknesses, or when a protocol spec requires it. Don't reach for it just because it sounds newer; "newer NIST standard" doesn't mean "better for your use case."
BLAKE3: fast, modern, not NIST-approved
BLAKE3 (released 2020) is the current speed champion for general-purpose hashing. On modern hardware with SIMD instructions it's typically 2–10× faster than SHA-256 on large inputs, while maintaining strong security margins. It also supports parallel hashing, variable-length output (XOF mode), and built-in key derivation — features that require extra plumbing with SHA-2.
You'll find BLAKE3 in Cargo (Rust's package manager uses it for build artifact caching), Bao (verified streaming), Zig's standard library, and a growing list of content-addressed systems. The b3sum CLI is the drop-in equivalent of sha256sum.
The catch: BLAKE3 has no FIPS approval. In regulated industries, government contracts, or any context requiring NIST-approved algorithms, it's out. If your context is internal tooling, file storage, or anything where performance matters more than compliance checkboxes, BLAKE3 is genuinely worth choosing over SHA-256.
Passwords: not any of the above
This is the category that keeps security engineers awake. General-purpose hash functions — SHA-256, SHA-3, BLAKE3, all of them — are engineered to be fast. That's precisely the wrong property for password hashing.
A modern GPU can compute billions of SHA-256 operations per second. A leaked database of SHA-256-hashed passwords, even with per-user salts, falls to a GPU dictionary attack in hours. The attacker just throws more hardware at the problem — and hardware gets cheaper every year.
For passwords, you need a purpose-built slow hash: Argon2id (winner of the 2015 Password Hashing Competition, now the standard per RFC 9106), bcrypt (solid since 1999, still widely supported), or scrypt (memory-hard, good alternative when Argon2 isn't available). These are designed to be expensive — tunable to consume seconds and gigabytes of RAM — so a database dump buys an attacker almost nothing without months of compute per password.
The hierarchy today: Argon2id first, scrypt as a fallback, bcrypt as a legacy option. SHA-anything for passwords means you're one breach away from a very bad day.
The short decision tree
Hashing passwords? Argon2id. Full stop. Hashing data for integrity, signing, or HMAC? SHA-256 by default, SHA-512 when you need larger output or 64-bit word efficiency, SHA-3 if you want structural diversity against a SHA-2 weakness, BLAKE3 if you need speed and aren't bound by FIPS. Dealing with legacy MD5 or SHA-1 in a non-security context? Leave it if changing it would break things — document it's not security-critical and don't extend the pattern. In a security context? Replace it now. Hash outputs are binary; pipe them through a base64 encoder when you need a URL-safe string for storage or transport.
Want a quick sanity check on what a given algorithm actually produces? Our hash generator runs MD5, SHA-1, SHA-256, and SHA-512 client-side — nothing leaves your browser — so you can compare output length and format against what your system is storing. MD5 and SHA-1 aren't universally dead. They're dead for specific uses. The mistake is treating hash selection as a one-size-fits-all question — it never was.
← All articles