Integrity

CRC32, MD5 and SHA-256: which one catches what

Three checksums, three different jobs. One detects accidental bit flips, one is fast and cryptographically broken, one is tamper-evident. Picking wrongly is how corruption goes unnoticed.

Files Corrupter ·

CRC32, MD5 and SHA-256: which one catches what

Checksums get treated as interchangeable, and they are not. Each of these was designed for a different threat, and using one where another belongs is a common and quiet mistake.

CRC32: accidental errors only

A cyclic redundancy check is not a hash in the cryptographic sense. It is a polynomial division over the message, chosen so that certain classes of error are guaranteed to be caught. CRC32 detects all single-bit errors, all double-bit errors within a bounded distance, and any burst error shorter than 33 bits. That is a mathematical guarantee, not a probability.

That is exactly what you want for a noisy channel, which is why CRC32 sits in Ethernet frames, in PNG chunks, and next to every entry in a ZIP archive.

What it cannot do is resist anyone deliberate. CRC32 is linear and trivially reversible: given a target checksum, you can compute bytes that produce it. It is an error detector, never a security control.

MD5 and SHA-1: fast, and broken for the wrong reasons

Both are cryptographic hashes whose collision resistance has failed. Practical MD5 collisions have existed for years, and SHA-1 fell to a demonstrated collision in 2017.

The nuance people miss is which property broke. Finding two different inputs with the same hash is now feasible. Taking a specific file and constructing a different file with that same hash, a preimage attack, is not. So MD5 remains perfectly serviceable for detecting accidental corruption, which is why it still appears next to downloads and inside deduplication systems.

It should never be used where an adversary chooses the input: not for signatures, not for password storage, not for verifying that a download was not tampered with by whoever served it.

SHA-256: tamper-evident

SHA-256 has no practical collision or preimage attacks. Publish the digest of a release over a channel an attacker does not control and any modification, random or deliberate, is detectable.

The cost is speed, and it is smaller than people assume. Modern x86 and ARM chips implement SHA-256 in hardware, and a checksum is almost never the bottleneck next to the disk read that feeds it.

Where each one actually lives

UseAlgorithmWhy
ZIP entry integrityCRC32Detects transfer damage cheaply
PNG chunksCRC32Per-chunk error detection
ZFS block checksumsSHA-256 by default, Blake3 in newer OpenZFSVerified on every read
Btrfs block checksumsCRC32CFaster, weaker, still catches bit rot
Git object namesHistorically SHA-1, moving to SHA-256Content addressing
Release verificationSHA-256Must resist a hostile mirror

The mistake that matters

The failure mode worth guarding against is verifying the wrong thing. A backup job that checksums the file it just wrote, using the copy still sitting in page cache, has verified almost nothing. It has confirmed that memory matches memory. The read that matters is the one that comes back off the platter or the NAND weeks later, which is the entire point of a filesystem scrub, discussed in silent data corruption and the filesystems that catch it.

The second mistake is treating a stored checksum as authoritative when it lives next to the data it protects. If the same corruption event can damage both, the check is decorative. Parity and checksums belong somewhere the failure cannot reach.

Trying it

Every run of the corrupter here can compute SHA-256 of the input and the output, which makes the change concrete rather than theoretical. Turn on the verify switch, create a corrupted copy, and compare the two digests. Then run the same file through twice and note that the digests differ each time, because the overwritten bytes come from crypto.getRandomValues rather than a fixed pattern.

If you are building restore verification on top of this, your backup is a hypothesis until you restore it covers where the check belongs in the process.