Hash Algorithms Compared: How to Choose Between MD5, SHA-1, SHA-256, and bcrypt
"Use MD5 to store passwords" still gets written into code by beginners in 2026 — and then waits for the breach that puts them on the front page.
Hash algorithms look like a simple "input to fixed-length string" mapping, but the gap between the right algorithm and the wrong one is huge: the former withstands billions of brute-force attempts, the latter has your users' passwords cracked in 5 minutes.
This article runs through all the mainstream hash algorithms — what can be used where, what can't, and why — plus the most common misuse patterns.
First Principles: Hash Is Not Encryption
Many people conflate "hash" and "encryption". Lock the concepts down:
| Aspect | Hash | Encryption |
|---|---|---|
| Direction | One-way (irreversible) | Two-way (decryptable) |
| Output length | Fixed | Depends on input |
| Goal | Verify integrity, generate fingerprints | Protect confidentiality |
| Needs a key | No (HMAC is the exception) | Yes |
| Typical use | Password storage, file verification, digital signatures | Data transport, file encryption |
Core properties of hashing:
- Deterministic — same input always produces the same output
- Irreversible — recovering the original from the hash is mathematically infeasible
- Avalanche effect — flip one input bit and the output changes completely
- Collision resistance — finding two different inputs with the same hash should be extremely hard
General-Purpose Hash Lineup
MD5: The Old Soldier That Should Have Retired
| Item | Value |
|---|---|
| Output length | 128 bits (32 hex chars) |
| Designed | 1991 |
| Status | Broken |
Known problems:
- 2004 — Wang Xiaoyun proved MD5 collision resistance is dead
- 2008 — researchers forged a CA certificate using 200 PS3s in a day
- Today, ordinary PCs produce collisions in seconds
Where it's still OK:
- Non-security integrity checks (a quick MD5 to verify a download isn't corrupted)
- Cache keys, dedup keys (anywhere there's no adversary)
Where it must not be used:
- Password storage
- Digital signatures
- Any security-related purpose
SHA-1: MD5's Wounded Sibling
| Item | Value |
|---|---|
| Output length | 160 bits (40 hex chars) |
| Designed | 1995 |
| Status | Broken |
Known problems:
- 2017 — Google published a real SHA-1 collision (SHAttered)
- Mainstream browsers and CAs stopped accepting SHA-1 certificates years ago
- Git still uses SHA-1 but is migrating to SHA-256
Verdict: same as MD5 — non-security only.
SHA-2 Family: The Current Workhorse
Contains SHA-224 / SHA-256 / SHA-384 / SHA-512:
| Algorithm | Output | Speed | Recommendation |
|---|---|---|---|
| SHA-224 | 224 bits | Medium | Rare |
| SHA-256 | 256 bits | Medium | ⭐⭐⭐ Default choice |
| SHA-384 | 384 bits | Slower | Niche |
| SHA-512 | 512 bits | Faster on 64-bit machines | ⭐⭐⭐ When longer hash is preferred |
Uses:
- File integrity verification
- Digital signatures
- Blockchain (Bitcoin uses SHA-256)
- HMAC building block
Note: SHA-256 is not appropriate for password storage (see the password section).
SHA-3: A Modern Backup
Standardized in 2015 (based on Keccak), structurally very different from SHA-2 — if SHA-2 ever breaks, SHA-3 is a seamless replacement.
| Algorithm | Output | Performance |
|---|---|---|
| SHA3-256 | 256 bits | Slightly slower than SHA-256 in software |
| SHA3-512 | 512 bits | Same |
Uses:
- When you want defense-in-depth against future SHA-2 breaks
- Ecosystem requirements (Ethereum uses Keccak-256)
BLAKE2 / BLAKE3: Fast and Safe
| Algorithm | Properties |
|---|---|
| BLAKE2 | Several times faster than SHA-2 with equivalent security |
| BLAKE3 | Further parallelized, single-thread exceeds 1 GB/s |
Uses:
- Performance-sensitive verification
- Content-addressable storage (IPFS uses BLAKE2/3)
- Default in modern crypto libraries (e.g., libsodium)
File Integrity Verification in Practice
After downloading a Linux ISO, verify the official SHA-256:
Compare with the value published on the official site — matching means the file is unaltered.
Why hash verification still allows MD5: this is an "adversary-free" scenario — you're guarding against transmission corruption, not someone deliberately forging files. Once there's an adversary (who could craft a collision), use SHA-256 or stronger.
Password Hashing: General-Purpose Hashes Don't Belong Here
Why SHA-256 Cannot Store Passwords
Counter-intuitive reason: SHA-256 is too fast.
Modern GPUs compute 10 billion SHA-256 hashes per second (this is what Bitcoin miners do). For password hashing, "fast" is fatal — it means an attacker who steals your hash table can brute-force at insane speed:
| Password length | Charset | GPU crack time |
|---|---|---|
| 6 chars | digits + letters | < 1 second |
| 8 chars | digits + letters | minutes |
| 10 chars | full character set | days |
Add rainbow tables (precomputed hash databases) and common passwords become near-instant lookups in SHA-256.
Hard Lessons from History
| Incident | What They Used | Outcome |
|---|---|---|
| Adobe 2013 (150M accounts) | 3DES encryption (not hashing) | Once broken, many passwords were exposed in plaintext |
| LinkedIn 2012 (165M accounts) | Unsalted SHA-1 | 90% of passwords recovered in 6 days |
| Equifax 2017 (147M users) | Plain text storage in some places | Company lost $5B in market cap |
One lesson: passwords must use a purpose-built password hash algorithm, not a general-purpose hash.
Purpose-Built Password Hash Algorithms
Design philosophy: be intentionally slow — make a single hash take tens to hundreds of milliseconds, so attackers' brute-force speed drops by millions of times relative to a fast hash.
| Algorithm | Year | Recommendation | Notes |
|---|---|---|---|
| bcrypt | 1999 | ⭐⭐⭐ | Reliable veteran, work factor adjustable |
| scrypt | 2009 | ⭐⭐ | Memory-hard, GPU-resistant |
| Argon2id | 2015 | ⭐⭐⭐ | Modern first choice, Password Hashing Competition winner |
| PBKDF2 | 2000 | ⭐ | Oldest standardized, weak GPU resistance, only for FIPS compliance |
Recommendation order:
- New projects: prefer Argon2id
- Existing bcrypt systems: keep using bcrypt, it remains safe
- PBKDF2: avoid unless required by FIPS compliance
bcrypt Usage
Key parameter: rounds (work factor) defaults to 10-12, each +1 doubles the compute time. Recommended:
- General apps: 12
- High-sensitivity: 14+
- Aim for ~250 ms per hash on your current server
Argon2id Usage
OWASP 2026 baseline: memory_cost=19 MiB, time_cost=2, parallelism=1 (minimum), tune upward based on server capacity.
About Salt
bcrypt and Argon2 automatically salt — the salt is baked into the output. You don't store it separately.
But if you see this kind of code, refactor immediately:
Just switch to bcrypt or Argon2.
HMAC: Hash with a Key
Anyone can compute a regular hash, but HMAC adds a key — only the key holder can compute the correct hash.
Uses:
- API request signing (anti-tampering + identity)
- HS256 algorithm in JWT
- Webhook verification
Security must-knows:
- Compare signatures with
hmac.compare_digest(), never with==— avoids timing attacks - Keys must be at least 256 bits random
Algorithm Selection Decision Tree
5 Classic Mistakes
Mistake 1: Storing Passwords with MD5/SHA-1
Replace with bcrypt or Argon2 immediately. For existing data: verify the old MD5 on next login, then immediately rehash with the new algorithm.
Mistake 2: Roll Your Own Salting on a General Hash
General hashes are too fast — no amount of salt defends against GPU brute force. Use a purpose-built password hash.
Mistake 3: HMAC Comparison with Equals
String == exits on the first mismatching character — attackers can infer signatures byte by byte from response time.
Mistake 4: Using Hash When You Need Encryption
Need reversibility? That's not a hash, that's encryption. Use AES-GCM or ChaCha20-Poly1305.
Mistake 5: Truncated Hash as Unique ID
8 hex chars = 32 bits of space = 50% collision probability under birthday attack at ~65k entries. Either use the full hash or use a real UUID.
Performance Reference
Single-threaded throughput on modern x86_64 CPUs (rough numbers — SHA-NI hardware acceleration and SIMD implementations push these significantly higher):
| Algorithm | Throughput |
|---|---|
| MD5 | ~600 MB/s |
| SHA-1 | ~700 MB/s |
| SHA-256 | ~400 MB/s (with SHA-NI: ~1.5 GB/s) |
| SHA-512 | ~600 MB/s (faster than SHA-256 on 64-bit) |
| BLAKE2b | ~1 GB/s |
| BLAKE3 | Single-thread ~1.5 GB/s, scales linearly with threads |
| bcrypt (cost=12) | ~3 ops/sec (intentionally slow) |
| Argon2id (64 MB) | ~30 ops/sec (intentionally slow and memory-heavy) |
Takeaway: for general-purpose use BLAKE3 is the speed king; for passwords slowness is the feature, not a bug.
Summary
Pin this cheat sheet to your brain:
| Scenario | Use |
|---|---|
| Password storage | Argon2id > bcrypt |
| File verification (with adversary) | SHA-256 / BLAKE3 |
| File verification (no adversary) | MD5 OK (SHA-256 better) |
| API signing | HMAC-SHA256 |
| Generic fingerprint | SHA-256 / BLAKE3 |
| Cache keys, dedup | MD5 / xxHash / BLAKE3 |
The single most important rule: general hashes (MD5/SHA-2/SHA-3/BLAKE) must never be used directly for password storage. Forget this, and the next breach headline could be your company's.
Generate hashes with the Hash Generator, generate strong passwords and keys with the Password Generator — together they cover roughly 80% of day-to-day crypto needs.