Frontend Labs
⋯

Chapter 9 — The real hash functions, and which are broken

In one sentence

MD5 and SHA-1 are broken and must not be used for security; SHA-2, SHA-3, and BLAKE2/3 are fine.

The table to memorise

Algorithm Output Status Use it?
MD5 128 bit BROKEN — collisions found in seconds Never for security. Non-security checksums only.
SHA-1 160 bit BROKEN — practical collisions (SHAttered, 2017; chosen-prefix, 2020) Never for new work
SHA-256 / SHA-512 (SHA-2) 256 / 512 bit Secure Yes — the default
SHA-3 / SHAKE variable Secure, different internal design Yes; useful as a hedge against SHA-2
BLAKE2 / BLAKE3 variable Secure, very fast Yes, where supported

What "broken" actually means

The distinction matters, because "MD5 is broken" is often over- and under-stated.

   COLLISION ATTACK  -- find ANY two inputs with the same hash.
      MD5:   seconds on a laptop
      SHA-1: ~2^63 work; done for real in 2017 (SHAttered)
      -> breaks SIGNATURES and CERTIFICATES

   CHOSEN-PREFIX COLLISION -- find a collision where you control both prefixes.
      MD5:   trivial
      SHA-1: demonstrated in 2020, ~$45k of compute at the time
      -> breaks practically everything; this is what killed SHA-1 for good

   PREIMAGE ATTACK -- given a hash, find AN input producing it.
      MD5:   still not practical
      SHA-1: still not practical
      -> so "MD5 of a strong random value" isn't instantly broken...
         but there is no reason to use it, and plenty of ways it bites you

Bottom line: MD5 and SHA-1 fail exactly where hashes matter most — proving that a document, certificate, or binary is the one you think it is.

The real-world consequences

Flame malware (2012) forged a Microsoft code-signing certificate using an MD5 chosen-prefix collision. It let malware appear to be a legitimate Windows Update. That is the practical meaning of "collisions break signatures".

SHAttered (2017) — Google and CWI produced two different PDF files with the same SHA-1 hash. Immediately afterwards, SHA-1 was removed from certificate issuance, and git had to add collision detection.

Choosing in practice

   General-purpose hashing, integrity, signatures    -> SHA-256
   Need extra margin / long-term                     -> SHA-512 or SHA-3-256
   Performance-critical (lots of data)               -> BLAKE3
   Hashing PASSWORDS                                 -> NONE OF THESE (Chapter 10)
   Legacy system compatibility only                  -> document the risk, plan removal

Simplified: SHA-512 is often faster than SHA-256 on 64-bit CPUs, despite the bigger output. If you want margin and speed, SHA-512 (or its truncated variant SHA-512/256) is a good pick.

Length-extension: a subtlety that matters

SHA-1 and SHA-2 have a structural quirk: given hash(secret || message) and the length of secret, an attacker can compute hash(secret || message || extra) without knowing the secret.

   NAIVE (broken):   token = sha256(secret + data)
                     -> attacker appends "&admin=true" and forges a valid token

   CORRECT:          token = HMAC-SHA256(secret, data)      (Chapter 11)

SHA-3 and BLAKE2/3 are immune by design. But the right answer is always HMAC, not picking a different hash.

Practice (25 min)

cd ~/sec-lab/scratch

# --- compare algorithms and their output sizes ---
for alg in md5 sha1 sha256 sha512 sha3-256; do
  printf "%-10s " "$alg"; printf 'hello' | openssl dgst -$alg 2>/dev/null | awk '{print $2}'
done

# --- speed comparison ---
openssl speed -evp sha256 2>/dev/null | tail -3
openssl speed -evp sha512 2>/dev/null | tail -3

# --- see a REAL MD5 collision ---
# Two different files, identical MD5. (Marc Stevens' classic example.)
curl -sO https://raw.githubusercontent.com/corkami/collisions/master/examples/free/md5_1.bin
curl -sO https://raw.githubusercontent.com/corkami/collisions/master/examples/free/md5_2.bin
cmp md5_1.bin md5_2.bin && echo "identical files" || echo "DIFFERENT files"
openssl dgst -md5 md5_1.bin md5_2.bin
openssl dgst -sha256 md5_1.bin md5_2.bin      # SHA-256 tells them apart

That last exercise is worth doing properly. Two files that differ, with the same MD5. Once you've seen it, "MD5 is broken" stops being abstract.

Break it: write a script that verifies a download using MD5. Then explain, in notes.md, exactly how an attacker who can also produce the "official" file defeats your check.

Common confusions

  • "MD5 is fine for checksums." For detecting accidental corruption, yes. For detecting deliberate tampering, no — and most checksum use is really about tampering.
  • "I'll use MD5 then SHA-256, two hashes are safer." Concatenating hashes is barely stronger than the stronger one alone. Just use SHA-256.
  • "SHA-256 is slow." It processes hundreds of MB/s per core, and most CPUs have hardware acceleration. It is not your bottleneck.
  • "More output bits = more secure." Only to a point. 256 bits is beyond any foreseeable brute force; going bigger buys margin, not necessity.

Check yourself

  1. What does it mean that MD5 is "broken"? Which property fails?
  2. Why does a collision attack break digital signatures?
  3. What is a length-extension attack, and what's the correct fix?
  4. Which hash should you use by default in 2026?

Further reading

  • Site: shattered.io — Google's SHA-1 collision announcement, with the two colliding PDFs. Excellent and accessible.
  • Repository: github.com/corkami/collisions — a collection of real hash collisions in many file formats. Superb for building intuition.
  • Guidance: NIST SP 800-131A — the official "which algorithms are still approved" document. Useful to cite in an argument.

Generated from real-life-guide.md · 8 Oct 2026 16:36