TechEarl

How to Verify a File Checksum on macOS (SHA-256)

Verify a file's SHA-256 checksum on macOS from the command line: compute it with shasum -a 256, check it against a published hash with -c, and know why SHA-256 (not MD5 or SHA-1) is the right choice in 2026.

Ishan Karunaratne⏱️ 8 min readUpdated
Share thisCopied
Verify a file's SHA-256 checksum on macOS with shasum -a 256, check it against a published hash with -c, and pick the right algorithm in 2026.

To verify a file's checksum on macOS, compute its SHA-256 hash and compare it to the one the publisher gave you:

bash
shasum -a 256 file.dmg

That prints a 64-character hex string. If it matches the value on the download page, the file arrived intact and unaltered. macOS ships shasum by default, so there is nothing to install.

The single most common mistake I see in old tutorials is shasum 1 file or shasum file. The first is missing the -a flag and is trying to select SHA-1; the second defaults to SHA-1 as well. SHA-1 has been broken since 2017 (Google and CWI published a real collision, "SHAttered"), and MD5 fell even earlier. Neither belongs in an integrity check anymore. The algorithm is chosen with -a, and the right value in 2026 is 256.

Compute a SHA-256 hash

The -a flag selects the algorithm. For file verification you want 256:

bash
shasum -a 256 ubuntu-24.04.iso

shasum -a accepts 1, 224, 256, 384, and 512. SHA-256 is the practical default: it is what almost every project publishes, it is fast, and it has no known weaknesses. Use 512 only if the publisher's checksum is SHA-512; there is no security reason to prefer it over 256 for ordinary downloads.

You can hash several files at once, which is handy when a release ships multiple artifacts:

bash
shasum -a 256 *.iso *.dmg

Verify by eye

The manual approach is to print the hash and read it against the published value:

bash
shasum -a 256 node-v22.0.0.pkg
# 7c... (compare this to the SHA256SUMS line on nodejs.org)

Hex hashes are case-insensitive, and tools disagree on casing: shasum prints lowercase, some sites publish uppercase. Do not let that trip you up. Rather than squinting at 64 characters, normalize both to lowercase and let the shell do the comparison:

bash
# Paste the published hash in place of PUBLISHED:
[ "$(shasum -a 256 node-v22.0.0.pkg | awk '{print $1}')" \
  = "$(echo 'PUBLISHED' | tr 'A-Z' 'a-z')" ] && echo MATCH || echo MISMATCH

That removes the human error of misreading one transposed character, which is the whole failure mode you are trying to avoid.

A cleaner one-liner is to feed a single hash filename line to shasum -c on stdin and let the tool do the recompute and compare. Note the two spaces between the hash and the filename (that is text mode, the format shasum -c expects):

bash
echo "PUBLISHED  node-v22.0.0.pkg" | shasum -a 256 -c -
# node-v22.0.0.pkg: OK

The trailing - tells shasum to read the checksum list from stdin. This is the same -c machinery covered below, just inlined for a single file, and it returns a non-zero exit code on a mismatch.

Verify against a checksum file (the right way)

Most projects publish a checksums file, often named SHA256SUMS or checksums.txt, with one hash filename line per artifact. shasum -c reads that file, recomputes each listed file, and tells you OK or FAILED:

bash
shasum -a 256 -c checksums.txt

Output looks like this:

bash
ubuntu-24.04.iso: OK
node-v22.0.0.pkg: OK

If a file was corrupted or tampered with, you get a clear failure instead of a hash you have to eyeball:

bash
ubuntu-24.04.iso: FAILED
shasum: WARNING: 1 computed checksum did NOT match

This is the mode to prefer. It scales to many files, it removes the manual comparison, and the exit code is non-zero on any mismatch, so you can use it in a script. To build your own checksum file for files you are distributing:

bash
shasum -a 256 *.iso > checksums.txt

A note on the format: each line is the hash, a space, a type indicator, then the filename. The default text mode uses a second space as that indicator, so you see two spaces (hash filename); binary mode replaces it with an asterisk (hash *filename). Most published SHA256SUMS files use the two-space text form. If a checksums.txt from elsewhere fails to parse, that spacing (or a stray carriage return from a Windows-edited file) is usually why.

The other tools on macOS: md5 and GnuPG

macOS also ships a BSD md5 command. Note the name: it is md5, not md5sum (that is the GNU/Linux name, and it is not on a stock Mac). The BSD tool also has no -a flag because it only does MD5:

bash
md5 file.dmg

Use md5 only for non-security work: a quick "did this large file copy correctly" check, or deduplicating files where you are not worried about an adversary. MD5 is fine for catching accidental corruption and useless against deliberate tampering, because anyone can craft two different files with the same MD5. For anything where the source could be malicious, including any download from the internet, use SHA-256.

A checksum proves integrity, not authenticity. It tells you the bytes match a known value; it does not tell you who produced that value. If an attacker can replace the download, they can usually replace the published checksum next to it. That is what cryptographic signatures are for. When a project ships a .asc or .sig alongside its checksums, verify the signature with GnuPG:

bash
brew install gnupg
gpg --verify SHA256SUMS.asc SHA256SUMS

A good signature means the checksum file itself came from the holder of that key, so a passing shasum -c on top of a verified signature is a real chain of trust.

Which algorithm, and when

AlgorithmmacOS commandUse it for
SHA-256shasum -a 256Verifying downloads, anything security-relevant. The default.
SHA-512shasum -a 512Only when the publisher's checksum is SHA-512.
SHA-1shasum -a 1Legacy compatibility only. Broken, never for security.
MD5md5Fast non-security dedup or accidental-corruption checks.

If you are scripting integrity checks across machines, the same hash that shasum -a 256 produces on a Mac is what sha256sum produces on Linux, so a checksums.txt is portable between them. The verify step on Linux is sha256sum -c checksums.txt, the same idea with the GNU command name.

FAQ

See also

Sources

Authoritative references this article was fact-checked against.

TagsshasumSHA-256checksummacOSmd5CLIfile integrity

Found this useful? Pass it on.

Copied

Ishan Karunaratne

Tech Architect · Software Engineer · AI/DevOps

Tech architect and software engineer with 20+ years building software, Linux systems, and DevOps infrastructure, and lately working AI into the stack. Currently Chief Technology Officer at a healthcare tech startup, which is where most of these field notes come from.

Keep reading

Related posts

How to Run a DNS Health Check on Your Domain

A practical DNS health check covers nameservers, A and AAAA records, MX, SPF, DKIM, DMARC, and CAA. Here is the full checklist, what each record actually tells you, and how to verify all of them in one pass.

How to Get Reliable JSON from an LLM

Get reliable JSON out of an LLM with native structured-output modes (Anthropic tool use, OpenAI Structured Outputs, Gemini schema), plus Zod / Pydantic validation as a fallback.