← Back to Blog

File Integrity Checks: From Hash Comparison to Safe Downloads

Despair after a failed download

A mirror site served a 500MB installer; extraction failed with a CRC error, and re-downloading cost an hour. If the page had shown a SHA-256 checksum and you'd spent 10 seconds computing and comparing after the download, you'd have dodged it on the spot. This article explains the principle, how to compute it, and what it can and can't defend against.

The principle: hashing makes 'sameness' verifiable

File checks rest on deterministic hashing:

file A ──SHA-256──▶ f5d0... (64 hex chars)
file B (one bit flipped) ──SHA-256──▶ 9a11... (completely different)
  • Same content → identical digest: identical bytes always yield the same digest;
  • Any single bit change → a different digest: flip one bit and the whole digest changes beyond recognition (avalanche effect).

So 'my digest equals the published digest' becomes strong evidence that 'this file matches the official bytes', catching transfer corruption, incomplete downloads and silent server-side corruption.

Computing it on the CLI

# Linux / macOS
sha256sum package.zip           # → <digest>  package.zip
md5sum   package.zip            # MD5 (not recommended for security, compatibility only)
shasum -a 256 package.zip       # built into macOS

# Windows (PowerShell)
Get-FileHash package.zip -Algorithm SHA256
Get-FileHash package.zip -Algorithm MD5

GUI is even simpler: any 'hash / checksum calculator' tool gives a 64- or 32-char digest on drag-in, ready to compare against the official value.

A standard verify-download flow

1. Get the file's SHA-256 checksum from the official/trusted source
2. Download the file
3. Compute SHA-256 locally once
4. Compare the 64-char digests (or use a tool's 'compare checksum' feature)
5. Match → intact and trustworthy; mismatch → discard, re-download, don't use the corrupt file

Key: obtain the checksum from a place independent of the download source (official page, signature file)—if it comes from the same hijacked source as the file, the comparison is meaningless.

The integrity vs anti-tamper boundary (honest)

Detects Can't detect
checksum compare corruption, incompleteness, silent damage an attacker rewriting the checksum too
official HTTPS / PGP / signature the above + partial defense vs targeted swap a leaked key itself

So: a checksum is the cheap first line against 'accidental'; trusted channels are the defense against 'deliberate.' Different scopes—don't conflate them.

Common pitfalls

  • File size as a checksum: meaningless; change content without changing size and it breaks;
  • A checksum from the same place as the download: zero one-way trust;
  • Computing but not comparing: ignoring the result is no defense;
  • Using CRC as a security hash: CRC only guards accidental bit errors; it lacks collision resistance and targeted-attack defense.

Self-check

Copy a SHA-256 sums from any official software page, download the matching installer, compute the local digest on the CLI, and compare char-by-char (by script or a tool) to confirm a match. Then flip one byte (a hex editor, +1 to some byte) and recompute—watch the 64-char digest change beyond recognition. Get both steps done and you both know how to use checksums and truly understand them.

Frequently Asked Questions

What is a checksum, and how is it different from a password hash?

A checksum is a **fixed-length, irreversible digest of the file's bytes**, e.g. SHA-256 emits 64 hex chars. It neither encrypts nor reconstructs—it exists for **comparison**: identical content always yields the same digest, and flipping one bit changes it entirely. The difference from password hashing is in *purpose and input model*: file checksums usually aren't salted and often cover public data—they answer 'did the transfer/storage stay intact'; password hashes must survive digest disclosure without revealing the plaintext, so they add salt and use deliberately slow algorithms to resist cracking.

Why does the same small file give a different MD5 every time?

It almost always reduces to 'the bytes aren't actually identical': ①different **newlines/encoding** (CRLF vs LF, BOM vs no BOM) change the byte stream; ②downloads from different sources carry different versions; ③the file was **opened and auto-resaved** by some viewer/editor (rewrites bytes/ mtime even without visible changes); ④you hashed the wrong thing (a directory vs a single file). To tell: compare the two files' first/last bytes with a hex/binary diff tool, or just re-run the hash once. MD5 itself is deterministic—same input, same output, always.

Can verifying a published SHA-256 sum really prevent tampering?

It detects **accidental corruption** reliably, but only partially defends against **targeted tampering**. Against corruption: bit flips in transit, partial loss and silent server damage all surface immediately on comparison. The limitation: if an attacker can also **replace the published checksum** (swap both the download and its sha256 for a malicious pair), the comparison 'fails consistently' toward the wrong answer. So against targeted attacks you still need a trusted channel: compare against the official HTTPS domain, PGP signatures, or a trusted package manager's signatures. Conclusion: a checksum is a cheap, high-value integrity line but not key-level forge-proofing.

Should my project verify sha256 on every dependency download? Is it too slow?

Worth doing, and usually fast: SHA-256 on a 256 MB file takes roughly a second or two (modern CPUs have hardware acceleration). For **security-critical** dependencies (binaries, artifacts crossing a trust boundary) write the expected digest into a lockfile/script and enforce it; for dev-cache assets change-detection is enough. For speed plus robustness use a faster checksum (BLAKE2/xxhash); for tamper-resistance use a lockfile plus official signatures rather than laziness. Note: 'large file size as checksum' carries zero integrity meaning—it's practically equivalent to nothing.

← Back to Blog