SHA-256 vs MD5 vs SHA-1: Which Hash Should You Use?
If you just need a safe default: use SHA-256.
But “hashing” shows up in a bunch of different places (file checksums, password storage, digital signatures, cache keys), and those scenarios don’t all need the same property.
This post is a practical guide to choosing between MD5, SHA-1, and SHA-256—with examples, gotchas, and a decision table you can actually use.
If you want to follow along, open the Hash Generator in another tab.
First: what a hash is (and what it isn’t)
A cryptographic hash function takes input bytes and produces a fixed-length output (the “digest”).
Two core properties people care about:
- Preimage resistance: given a hash, it’s infeasible to find an input that produces it.
- Collision resistance: it’s infeasible to find two different inputs with the same hash.
Most real-world breakages (MD5, SHA-1) are about collisions, not “someone reversed the hash.”
Also: hashing is not encryption. There’s no key. If you need secrecy, you want encryption. If you need integrity, you want a MAC or signature. Hashes are a building block, not the whole house.
MD5 vs SHA-1 vs SHA-256: the quick comparison
Here’s the practical snapshot:
| Algorithm | Digest size | Security status (2026) | Use it for… | Avoid it for… |
|---|---|---|---|---|
| MD5 | 128-bit | Broken for collisions | Non-security checksums where you’re OK with collisions | Signatures, certificates, tamper-proofing, “unique” IDs |
| SHA-1 | 160-bit | Broken for collisions; being phased out | Legacy compatibility only | Anything security-sensitive (signing, integrity, trust) |
| SHA-256 (SHA-2) | 256-bit | Current standard default | Integrity, signing inputs, general cryptographic hashing | Password storage (use bcrypt/scrypt/Argon2 instead) |
NIST’s stance is blunt: SHA-1 is at end-of-life and they recommend migrating to SHA-2 or SHA-3 as soon as possible. (See: NIST, “NIST Retires SHA-1 Cryptographic Algorithm,” 2022.)
The part that trips people up: “checksum” vs “security”
If your goal is “did this file get corrupted during download?”, a checksum is mostly about catching random errors.
If your goal is “did an attacker modify this file but keep the checksum the same?”, now you’re in collision-resistance territory.
Those are different threat models.
Example: download verification
If you publish a release and also publish a hash:
- OK:
SHA-256(myfile.zip)in aSHA256SUMSfile. - Not OK:
MD5(myfile.zip)as the only integrity proof.
Why? If an attacker can swap the file, they can try to craft a different file with the same MD5 (collision attack). That’s why MD5 is no longer considered prudent when collision resistance is required (IETF RFC 6151).
Why MD5 is considered “broken”
MD5 was specified in 1992 (RFC 1321) with the expectation that collisions would be infeasible. That assumption didn’t hold.
The important part isn’t that any collision exists—it’s that collisions are practical enough that protocol designers and standards bodies stopped trusting MD5 for collision-resistant use cases.
The IETF explicitly says it’s “not prudent to use MD5 when collision resistance is required.” (RFC 6151, 2011.)
When MD5 is still used (and why it’s not always crazy)
You’ll still see MD5 in:
- ETags / caching (as a quick content fingerprint)
- Deduping (“do these two blobs look the same?”)
- Non-adversarial checksums (catching corruption)
If nobody is trying to trick you, MD5 can be a fast fingerprint.
But if there’s an attacker in the loop, MD5 should not be your integrity mechanism.
Why SHA-1 is also a bad default now
SHA-1 hung around longer than MD5, but it’s also considered collision-broken.
NIST’s current public guidance is to phase SHA-1 out and migrate to SHA-2/SHA-3 (NIST, 2022). On the standards side, the IETF deprecated MD5 and SHA-1 signature hashes in TLS 1.2 (RFC 9155, 2021).
So if you’re choosing today, SHA-1 usually only wins on one criterion: compatibility with something old.
Why SHA-256 is the default recommendation
SHA-256 is part of the SHA-2 family defined by NIST in the Secure Hash Standard (FIPS 180-4).
In practice, SHA-256 gives you:
- A digest size that’s comfortably beyond where collision attacks are realistic today
- Broad support across languages, databases, and tooling
- A “boring” algorithm choice that won’t surprise auditors
If you’re adding a “hash this” feature to a product and you don’t have a strong reason otherwise, SHA-256 is the safe default.
Try it quickly with our Hash Generator:
- Input:
hello world - SHA-256 output starts with:
b94d27b9934d...
(Yes, developers memorize that one. It’s the “hashing hello world” equivalent of 127.0.0.1.)
Common use cases (with the right choice)
1) Hashing passwords (don’t use any of these)
This is the big one.
Even SHA-256 is not a password hashing algorithm.
Why? Password hashing needs to be slow and memory-hard so attackers can’t do billions of guesses per second on GPUs/ASICs.
Use Argon2, scrypt, or bcrypt instead.
If you must understand the difference in one sentence: SHA-256 is designed to be fast and consistent; password hashing is designed to be slow and expensive.
If you’re working on auth flows, you may also want our Password Generator for test accounts and fixtures.
2) File integrity checksums (downloads, backups)
Use SHA-256 unless you’re explicitly in a “no attacker” scenario and need MD5 for legacy tooling.
- Publishing release artifacts? SHA-256.
- Verifying backups weren’t corrupted? SHA-256.
- Internal pipeline where corruption is the only threat? MD5 can be acceptable, but I still default to SHA-256 because the performance difference usually doesn’t matter.
3) Digital signatures / certificates
Avoid MD5 and SHA-1.
In 2026, if you’re signing anything (certificates, firmware, documents), SHA-256 is the minimum baseline most teams expect.
4) API request signing / webhooks
If you need to prove “this request came from X” and wasn’t modified, you want an HMAC (keyed hash), not a plain hash.
Use HMAC-SHA-256 as the common default.
A plain SHA-256 hash of the payload is not authentication, because anyone can compute it.
5) “Unique IDs” / dedupe keys
If you’re using a hash as a convenient identifier (e.g., keying by content hash):
- Prefer SHA-256 if collisions would be a real bug or security issue.
- MD5 is sometimes used for performance, but you should only do it if collisions are acceptable and you understand the risk.
If you need a proper unique identifier that’s not derived from content, use a UUID. (Related: UUID guide: when and how to use them.)
Code examples: SHA-256 in the real world
Node.js (built-in crypto)
import { createHash } from "node:crypto";
const input = "hello world";
const sha256 = createHash("sha256").update(input, "utf8").digest("hex");
console.log(sha256);
Python
import hashlib
input_bytes = b"hello world"
sha256 = hashlib.sha256(input_bytes).hexdigest()
print(sha256)
CLI (macOS/Linux)
printf "hello world" | sha256sum
Edge case: echo "hello world" | sha256sum includes a trailing newline on most shells, so you’ll get a different hash. printf avoids that.
Edge cases and “gotchas” I see in real systems
Gotcha 1: hashing strings vs bytes
Hashes are defined over bytes, not “text.” If two systems disagree about encoding (UTF-8 vs UTF-16) or normalization (NFC vs NFD for Unicode), you’ll get mismatched hashes.
If you’re hashing user-facing text, define the exact encoding and normalization.
Gotcha 2: comparing hashes securely
If you’re comparing digests for authentication (like webhook signatures), use a constant-time comparison function to avoid timing leaks.
In Node, that’s timingSafeEqual. In many languages, there’s an equivalent.
Gotcha 3: “SHA-256 makes it secure”
People sprinkle SHA-256 on a broken design and call it a day. Two common examples:
- Password storage with plain SHA-256 (fast → easy to brute-force)
- “Signing” a request by hashing the payload (no key → no authentication)
SHA-256 is a good primitive, but you still need the right construction (HMAC, signature, KDF).
FAQ
Is SHA-256 always better than SHA-1?
For security-sensitive use cases, yes—because SHA-1’s collision resistance is considered broken and it’s being phased out. SHA-256 is the modern baseline.
Can I use MD5 for checksums?
If you’re only catching accidental corruption and there’s no attacker trying to trick the checksum, MD5 can be “good enough.”
If you’re publishing hashes for downloads, verifying updates, or doing anything where tampering matters, don’t use MD5.
What about SHA-512?
SHA-512 is fine too, and sometimes faster on 64-bit CPUs. But SHA-256 is widely used, widely supported, and usually the simplest “just pick one” answer.
If SHA-256 is secure, why not use it for passwords?
Because it’s fast.
Attackers don’t “reverse” password hashes. They guess passwords and hash their guesses. With a fast hash, they can do billions of guesses per second.
Use Argon2/scrypt/bcrypt for password hashing.
Wrapping up
If you’re choosing today:
- Default: SHA-256
- Legacy compatibility only: SHA-1
- Non-adversarial fingerprints only: MD5
And if you want to sanity-check a value quickly, the Hash Generator runs entirely in your browser.
Sources
- NIST, FIPS 180-4: Secure Hash Standard (SHS): https://csrc.nist.gov/pubs/fips/180-4/upd1/final
- IETF, RFC 1321: The MD5 Message-Digest Algorithm: https://www.rfc-editor.org/rfc/rfc1321.html
- IETF, RFC 6151: Updated Security Considerations for the MD5 Message-Digest and the HMAC-MD5 Algorithms: https://datatracker.ietf.org/doc/html/rfc6151
- NIST, NIST Retires SHA-1 Cryptographic Algorithm (2022): https://www.nist.gov/news-events/news/2022/12/nist-retires-sha-1-cryptographic-algorithm
- IETF, RFC 9155: Deprecating MD5 and SHA-1 Signature Hashes in TLS 1.2 and DTLS 1.2 (2021): https://datatracker.ietf.org/doc/html/rfc9155
Try the tool mentioned in this article:
Open Tool →