Why Download Pages Still Publish MD5 Checksums

By Freddy ·

Open the download page for an older Linux distribution, a database driver, or a firmware image and there is a good chance you will find a 32-character hex string labelled MD5 sitting next to the link. Everyone who has read about hash functions knows MD5 is broken, so the string looks like negligence. It is mostly habit, and in the situation the checksum was designed for, it still does its job. The more useful question is what that job is, because the answer shows when the string protects you and when it is decoration.

Why publishers keep doing it

Reasons are unglamorous. Release scripts written fifteen years ago emit MD5 and nobody has touched them. Mirrors and package tooling expect an .md5 file. Every operating system ships a tool that can compute one. A 32-character value is also easier to read aloud or paste into a ticket than a 64-character SHA-256. None of these reasons is a security argument, which is worth keeping in mind.

What the checksum does well

If a download is cut short, a mirror serves a half-synced file, or a flaky connection flips some bits, the MD5 of what you received will not match the published value. For random damage like that, the chance of an accidental match is about 1 in 2128, which is as good as never. MD5 is also cheap to compute on a multi-gigabyte image. As an error detector it works, and the known weaknesses of MD5 are irrelevant to it, because random corruption is not trying to be clever.

What it does not do

The weakness people cite is collision attacks, where an attacker builds two different files with the same hash. That needs the attacker to create both files. Against a download page the harder question comes first: where does the checksum come from? If the page and the file sit on the same server and an attacker can replace the file, they can replace the number next to it too, and your verification passes on malware. Switching that number from MD5 to SHA-256 changes nothing in this scenario. A hash published through the same channel as the file proves the two agree with each other, and nothing about whether either is the one the author released. The gap is the same one covered in HMAC vs plain hashing: a bare hash says the data is unchanged, not who produced it.

Where the MD5 weakness does bite

Collisions matter when someone with a motive can influence what gets hashed before it is trusted. The well-known case is the Flame malware, discovered in 2012, which used a chosen-prefix MD5 collision to forge a Microsoft code-signing certificate that Windows accepted. The attacker controlled part of the data being signed, and the signature covered an MD5 hash. The same logic applies to any scheme where an outsider can submit a file that is later signed or whitelisted by its hash. A different property, finding a file that matches a hash you were handed, called a preimage attack, remains impractical for MD5. So a checksum from a trusted source still cannot be matched by a forged file, which is the main reason MD5 downloads have not been abused in practice.

How to check one yourself

# Linux
md5sum ubuntu.iso

# macOS
md5 ubuntu.iso

# Windows (PowerShell)
Get-FileHash .\ubuntu.iso -Algorithm MD5

# Windows (Command Prompt)
certutil -hashfile ubuntu.iso MD5

Compare the output with the published value character by character, or paste both into a diff to be sure. A known reference helps when you doubt your tooling: the MD5 of the empty string is d41d8cd98f00b204e9800998ecf8427e and of the text abc is 900150983cd24fb0d6963f7d28e17f72, both from the RFC 1321 test suite. You can reproduce them in the Encrypt / Decrypt tool, which hashes text in your browser and shows a legacy warning when MD5 is selected.

Three ways the check itself goes wrong

Matching only the start of the string. Comparing the first six characters feels thorough and is not. Near-matches are trivial to produce deliberately, so compare the whole value, or let a tool do it.

Hashing a different file than the one listed. Some pages publish the checksum of the compressed archive, others of the extracted image inside it. If your result never matches, check which artifact the value refers to before assuming the download is damaged.

Hand-comparing when a tool can do it. Many projects ship a checksum file in the form hash filename. On Linux, md5sum -c ubuntu.iso.md5 reads that file, hashes the named file, and prints OK or FAILED, which removes the squinting step entirely. The same pattern works with sha256sum -c when a SHA-256 list is provided.

What to look for on a download page

Treat an MD5 beside a link as a corruption check and nothing more. For software you will run with real privileges, prefer a page that gives a SHA-256 value and a detached signature (a .asc or .sig file) you can verify against a key you obtained separately, or that serves the checksum from a different host than the file. If the checksum and file share one server with no signature, the strength of the hash does not matter much. The comparison to SHA-256 vs MD5 covers the algorithm question. The trust question comes first.

← Back to KeyForge