Security
MD5 vs SHA-256 vs bcrypt — Which Hash to Use and Why
MD5 vs SHA-256 vs bcrypt explained — what each hash is for, why MD5 is broken, when SHA-256 is right, why passwords need bcrypt, and benchmark comparisons.
"What hash function should I use?" depends entirely on what you are protecting and from whom. MD5, SHA-256, and bcrypt are all "hash functions," but they exist for completely different reasons. Picking the wrong one is one of the most common security mistakes in production code.
This guide explains the differences, when to use each, and which to avoid for which job.
Quick Answer
| Use case | Right answer | Why |
|---|---|---|
| Verifying a downloaded file is intact | SHA-256 | Fast, collision-resistant, not broken |
| Storing user passwords | bcrypt (or Argon2) | Deliberately slow; resistant to GPU cracking |
| A non-security checksum (cache key, deduplication) | SHA-256 or even xxHash | MD5 still works here, but SHA-256 future-proofs you |
| Anything new touching security | Never MD5 | It is broken; pick SHA-256 or stronger |
What Each One Actually Is
MD5
MD5 produces a 128-bit (16-byte, 32 hex characters) hash. Designed in 1992. It is cryptographically broken — researchers can produce two different inputs that hash to the same output (a collision) on a laptop in seconds. You should not use MD5 for anything where "two files have the same hash" could be a security problem.
md5("hello world") = 5eb63bbbe01eeed093cb22bb8f5acdc3
SHA-256
SHA-256 produces a 256-bit (32-byte, 64 hex characters) hash. Part of the SHA-2 family, standardized by NIST in 2001. It is the modern default for cryptographic integrity. No practical collision attacks are known after 25 years of analysis.
sha256("hello world") = b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
bcrypt
bcrypt is not a general-purpose hash — it is a password hashing function, specifically designed to be slow. It includes a built-in salt and a configurable cost factor that multiplies the work required.
bcrypt("hello world", cost=10) = $2b$10$f48eVbXP...kxqVo8q (60 chars, base64)
Same input run twice produces different outputs (because of the random salt). To verify a password, you compare using bcrypt.checkpw() rather than re-hashing.
Why MD5 Is Broken (And When That Matters)
A "broken" hash means an attacker can:
- Find collisions — produce two different inputs with the same hash.
- In some cases, find a second preimage — given a hash, find an input that produces it.
For MD5, collisions are not just theoretical — they are practical. In 2008, researchers used MD5 collisions to forge a fake SSL certificate. In 2012, the Flame malware used an MD5 collision to fake a Microsoft signature.
Does this mean MD5 is "useless"? Not quite. For non-security purposes — fast hashing for hash tables, deduplication, or cache keys — MD5 still functions. But for anything related to integrity or trust, MD5 is out.
If you are starting a new project today, just use SHA-256 everywhere MD5 was tempting. The performance difference is negligible.
Why You Cannot Use SHA-256 for Passwords
SHA-256 is too fast.
A modern GPU can compute around 10 billion SHA-256 hashes per second. If an attacker steals your password database, they can try every 8-character password in the English dictionary in milliseconds. Adding salt prevents precomputed rainbow tables, but it does not slow down the per-guess work.
bcrypt is designed for the opposite — it is intentionally slow. The cost factor controls how slow:
- Cost 10 → about 100 ms per hash
- Cost 12 → about 400 ms per hash
- Cost 14 → about 1.6 seconds per hash
For a legitimate login, 100 ms is invisible. For an attacker trying billions of passwords, it is fatal. They go from 10 billion guesses/second to about 10 guesses/second — a billion times slower.
This is why password = SHA-256(password + salt) is wrong, even though it sounds right.
Performance: How Different Are They?
Rough numbers on a modern laptop CPU, single-threaded:
| Function | Speed | Use |
|---|---|---|
| MD5 | ~500 MB/s | Legacy / non-security |
| SHA-256 | ~400 MB/s | General-purpose crypto hash |
| bcrypt (cost 10) | ~10 per second | Passwords |
| Argon2 (default) | ~5 per second | Passwords (newer than bcrypt) |
MD5 and SHA-256 are both fast enough to hash gigabytes per second. bcrypt deliberately tops out around 10 operations per second. That is the whole point.
Code Examples
Python — SHA-256
import hashlib
h = hashlib.sha256(b"hello world").hexdigest()
print(h)
# b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
Python — bcrypt for passwords
import bcrypt
# Hash a password (do this when the user signs up)
password = b"correct horse battery staple"
hashed = bcrypt.hashpw(password, bcrypt.gensalt(rounds=12))
# Verify a password (do this on login)
if bcrypt.checkpw(password, hashed):
print("password matches")
JavaScript — SHA-256 in the browser
async function sha256(text) {
const buf = new TextEncoder().encode(text);
const hash = await crypto.subtle.digest("SHA-256", buf);
return [...new Uint8Array(hash)]
.map(b => b.toString(16).padStart(2, "0"))
.join("");
}
sha256("hello world").then(console.log);
Node.js — bcrypt
const bcrypt = require("bcrypt");
const hashed = await bcrypt.hash("correct horse battery staple", 12);
const matches = await bcrypt.compare("correct horse battery staple", hashed);
What About Argon2?
Argon2 is the newest password hashing function — it won the 2015 Password Hashing Competition and is the recommendation in modern guidance (OWASP, IETF). Argon2id is the variant you want.
Should you switch from bcrypt to Argon2? If you are building a new system, yes. If you are running an existing bcrypt installation and it is properly configured (cost ≥ 12), there is no urgency.
bcrypt is still good. Argon2 is just better.
Frequently Asked Questions
Is MD5 still safe for non-password use?
For non-security purposes (deduplication, sharding, cache keys), MD5 still works. It is not slower or less correct than SHA-256 for those jobs — it is just smaller (16 bytes vs 32). For anything where "an attacker forging a hash collision matters," it is unsafe.
Can I just use SHA-256 for passwords with a salt?
No. Salts prevent rainbow-table attacks but do nothing about per-guess speed. An attacker with a stolen database and GPUs can still grind through 10 billion guesses per second. You need a slow function — bcrypt, scrypt, or Argon2.
Is bcrypt secure in 2026?
Yes, with cost ≥ 12. The main concern is hardware getting faster — Moore's Law eventually means today's cost 12 becomes tomorrow's cost 10. Bump the cost factor every few years.
Is SHA-512 better than SHA-256?
SHA-512 produces a longer hash (64 bytes vs 32) and is sometimes slightly faster on 64-bit CPUs. Cryptographically, both are considered safe. For most use cases SHA-256 is enough; SHA-512 is overkill but not harmful.
What is SHA-3?
SHA-3 is a different family of hash functions (based on Keccak), standardized in 2015 as a backup in case SHA-2 ever falls. It is not "newer SHA-2." SHA-256 and SHA3-256 are both fine; in practice, SHA-256 is more widely supported.
Why does bcrypt produce a different hash every time?
Because it includes a random salt in each hash. That salt is stored inside the output string. When you verify, bcrypt extracts the salt, re-runs the hash with the same salt and cost, and compares. This is why you call bcrypt.checkpw(password, hashed) instead of hashing the input and comparing strings.
Can I migrate from MD5 / SHA-256 passwords to bcrypt without forcing a password reset?
Yes. On next login, when the user supplies their plaintext password, hash it with the old function, compare to your stored hash, and if it matches, re-hash with bcrypt and replace the old record. Within a few weeks of normal logins your database is migrated. Users who never log in can be force-reset.
What hash should I use for file integrity (checksums)?
SHA-256. It is the default for Linux distributions, Git objects (which use SHA-1 historically and SHA-256 going forward), and most package managers. MD5 still appears in legacy MD5SUMS files but should not be used in new systems.
Try It Yourself
You can compute all of these in your browser — no signup, nothing leaves your machine:
For a deeper reference on every algorithm, the Hash Lab covers 45+ hash functions with interactive demos and 450+ MCQs.
Want to learn more?
Explore free chapter-wise notes with quizzes and code playground
Prefer watching over reading?
Subscribe for free.