← Blog Β· May 9, 2026 Β· dev, security

MD5, SHA-256, bcrypt, Argon2: Which Hash Function to Use

Hash function choice is one of the few areas where picking wrong has serious consequences. Use MD5 for password storage and you'll be breached eventually. Use bcrypt for file checksums and you'll waste compute. Here's how to choose.

What a hash function does

A hash function takes any input and produces a fixed-length output (the digest). Same input β†’ same output, always. Tiny change to input β†’ completely different output. You can't reverse it (in theory) and you can't find two inputs that produce the same output (in theory).

Try it: our hash generator computes MD5, SHA-1, SHA-256, SHA-384, SHA-512 for any text input.

The four use cases

1. File integrity / checksums

Use case: "Did this file change since I last saw it?" or "Did the download get corrupted?"

Recommended: SHA-256. Modern default.

Acceptable: MD5 if you control both ends and there's no adversary. Still used by Git (which uses SHA-1) and many package managers because the threat model is "detect accidental corruption" not "detect adversarial substitution."

2. Cryptographic identity / signatures

Use case: "Sign this document so we can prove it hasn't been tampered with."

Recommended: SHA-256 (most common) or SHA-512.

Never: MD5 or SHA-1. Both have practical collision attacks. SHA-1 was deprecated in 2011 and broken in practice by 2017 (Google's SHAttered attack).

3. Password storage

Use case: "Store user passwords so even if the DB leaks, attackers can't reverse them."

Recommended: Argon2id (2015 winner of the Password Hashing Competition). Configurable memory cost, time cost, parallelism.

Acceptable: bcrypt. 25 years old, battle-tested, slow enough to thwart brute force. Capped at 72 bytes of input (annoying for passphrases).

Also OK: scrypt. Memory-hard like Argon2 but older.

Never use plain MD5, SHA, etc. for passwords. They're too fast β€” an attacker with a GPU farm can try billions of guesses per second. Argon2 with default settings takes ~100ms per guess, dropping that to ~10 per second.

4. Hash maps / dictionaries / Bloom filters

Use case: Non-cryptographic, just need a good distribution to bucket values.

Recommended: xxHash, MurmurHash, FNV. Very fast, no security guarantees needed.

Cryptographic hashes work but are 100Γ— slower than needed for this case.

Why is MD5 broken?

MD5 was designed in 1991. By 2004 researchers could find collisions (two inputs that produce the same hash) in seconds. By 2008 attackers could create rogue SSL certificates. By 2012 the Flame malware used MD5 collisions to spread via Windows Update.

Note: "broken for collision resistance" doesn't mean "reversible." You still can't recover the input from an MD5 hash. But you CAN find another input with the same hash, which breaks digital signatures.

Why are MD5/SHA bad for passwords?

Speed. MD5 takes about 1 nanosecond per hash. SHA-256 takes 10-20 ns. An attacker with a $500 GPU can compute ~30 billion SHA-256 hashes per second. So if you stored passwords as SHA-256 and someone steals your database, common passwords are cracked in seconds.

Password hashing functions are designed to be slow. bcrypt at cost factor 12 takes ~250ms per hash. Argon2 with memory cost 64MB takes ~100ms and uses memory that GPUs can't cheaply parallelize. That's a slowdown of about 1 billionΓ—.

Salting

A salt is random data appended to a password before hashing. Without it, two users with the same password produce identical hashes β€” attackers can use pre-computed "rainbow tables" to crack many at once.

bcrypt, Argon2, scrypt all include salting automatically. If you're considering rolling your own (don't), make sure each password gets a unique random salt of at least 16 bytes.

SHA-1, SHA-2, SHA-3?

Default to SHA-256 unless you have a reason to choose differently.

HMAC

HMAC (Hash-based Message Authentication Code) is a way to use a hash function to produce a MAC β€” a tag that verifies both integrity AND authenticity. Used in JWT (with HS256), webhook signatures (GitHub, Stripe, etc.), and TLS.

HMAC-SHA256 is what most JWT libraries use under the "HS256" algorithm. See our JWT decoder for examples.

Decision tree

  1. Storing passwords? β†’ Argon2id (or bcrypt)
  2. Signing data? β†’ HMAC-SHA256
  3. Detecting accidental corruption? β†’ SHA-256 (or MD5 if you're ok)
  4. Adversarial integrity? β†’ SHA-256 minimum
  5. Hash table / Bloom filter? β†’ xxHash, MurmurHash

Tools

← All blog posts