A hash function takes an input of any size and produces a fixed-size output (a "digest") such that the same input always produces the same output, and even a tiny change to the input produces a completely different output. MD5 and SHA-256 both do this — the question is which properties you actually need.
What "MD5 is broken" actually means
MD5 produces a 128-bit digest and was designed for cryptographic security, but practical collision attacks were demonstrated in 2004 — meaning it's possible to deliberately construct two different inputs that produce the identical MD5 hash. That's fatal for any security use case: if an attacker can craft a malicious file with the same MD5 as a legitimate one, MD5 can't be trusted to detect tampering. SHA-1 (160-bit) suffered the same fate later, with a practical collision demonstrated in 2017.
Crucially, "broken" here means broken for security guarantees, not broken as a function — MD5 still reliably produces a fixed, deterministic digest, which is why it hasn't disappeared entirely.
Where MD5 (and SHA-1) are still fine to use
- Checking for accidental file corruption during a transfer (not adversarial tampering)
- Generating a quick, non-security cache key or deduplication fingerprint for identical file detection
- Legacy system compatibility where you have no choice
The line is intent: if the hash is only defending against accidents, MD5's speed is a fine trade-off. If anyone might have an incentive to deliberately produce a matching hash — password storage, digital signatures, verifying a downloaded file hasn't been tampered with by an attacker — MD5 and SHA-1 are the wrong tool.
Where SHA-256 is the right default
- Verifying software downloads against a publisher-provided checksum
- Blockchain and cryptographic applications
- Any integrity check where tampering is a real threat model
- General-purpose "give me a strong, standard hash" default when you're not sure what the future requirement will be
One important caveat: SHA-256 is not the right tool for hashing passwords, despite being cryptographically strong. It's designed to be fast, and speed is exactly the wrong property for password storage — it makes brute-force attacks cheaper. Password hashing needs an algorithm designed to be slow and memory-hard, like bcrypt, scrypt, or Argon2, not a general-purpose hash function.
Quick decision guide
- Detecting accidental corruption → MD5 or SHA-1 is fine
- Verifying integrity against tampering → SHA-256 (or SHA-3)
- Hashing passwords → none of the above; use bcrypt/Argon2
- Not sure → SHA-256 is the safe general default