Article

How to Verify Mac App Downloads Before You Install Them

macOS does a lot of verification for you. Gatekeeper checks notarization. XProtect scans for known malware. The Mac App Store reviews everything it ships. For most downloads, double-clicking is enough. But for high-stakes installs — anything that asks for admin rights, anything that handles your wallet or credentials, anything from a smaller developer you don't recognise — manual verification is the difference between "probably fine" and "definitely the file the developer published."

This guide walks through the practical verification steps in 2026: SHA-256 checksums, GPG signatures, Apple's codesign and spctl tools, VirusTotal as a second opinion, and the workflow for inspecting a PKG before it ever runs.

Why bother verifying

Three real attack vectors target Mac downloads in 2026:

  • Compromised developer accounts. Attackers occasionally hijack legitimate update infrastructure and ship modified versions briefly. Notarization usually catches these but not always immediately.
  • Mirror sites and search-result phishing. Top Google or Bing results for "download App X" frequently include lookalike sites that wrap a modified version of the real app.
  • Man-in-the-middle on HTTP downloads. Rare in 2026 because most sites are HTTPS, but still possible on public Wi-Fi if a download uses HTTP or if a captive portal injects scripts.

Verification mitigates all three. A SHA-256 checksum or signature published by the developer proves the file you have is bit-for-bit identical to the file they published, regardless of how it got to you.

SHA-256 checksums — the fast first check

A checksum is a fingerprint of the file's contents. Change one byte of the file and the SHA-256 changes completely. Developers publish a checksum on their download page (or in a release note); you compute the checksum of your local download and compare.

On macOS, the command is built in:

  • shasum -a 256 path/to/file.dmg — compute SHA-256.
  • shasum -a 512 path/to/file.dmg — SHA-512 for stronger algorithms when developers publish them.
  • md5 path/to/file.dmg — MD5 is weak and shouldn't be relied on for security, but is sometimes the only checksum a project publishes.

Compare the output to the value on the developer's page. They must match exactly — every character. If they differ, do not install. Re-download from the official source and recompute. If the second attempt also differs, contact the developer.

One important caveat: a checksum is only as trustworthy as the page it came from. If an attacker controls both the file and the page, they will publish a checksum that matches their modified file. Checksums prove the file matches what the page claims, not that the page is genuine. For higher assurance, use a GPG signature instead.

GPG signatures — the strongest single-tool verification

GPG signatures cryptographically prove the file was signed by someone who controls a specific GPG key. To verify:

  • Install GPG: brew install gnupg.
  • Import the developer's public key from a trusted source (typically published on their site or on a public key server). Example: gpg --recv-keys <KEY_FINGERPRINT>.
  • Verify: gpg --verify file.dmg.sig file.dmg.

A correct signature returns "Good signature from [Developer Name]". GPG will also tell you whether you've manually marked the key as trusted; this matters because anyone can upload a key with any name to a key server. To raise trust further, find the same key fingerprint published in multiple independent places (developer site, GitHub profile, project documentation, third-party security database) and confirm they match.

GPG verification is overkill for typical app downloads but is standard practice for things like cryptocurrency wallet binaries, full-disk-encryption tools, security utilities, and Linux distributions. When a developer offers a GPG signature, use it.

Apple's built-in tools: codesign and spctl

macOS verifies code signatures and notarization automatically when you launch an app. The same checks are available via two command-line tools so you can verify before launching.

codesign

Inspects an app bundle's code signature:

  • codesign -dvv /Applications/AppName.app — verbose details about the signature.
  • codesign --verify --verbose /Applications/AppName.app — checks that the signature is intact and matches the binary.

What to look for in the output:

  • Authority= lines listing the signing certificate chain. The top should be Apple Root CA. The middle should be Developer ID Certification Authority. The bottom should be the developer's Apple Team ID — verify it matches the developer.
  • TeamIdentifier= the developer's 10-character team ID. Cross-check on the developer's site if you want to be sure.
  • Sealed Resources version= indicates the app's resources are bound to the signature; tampering with files inside the .app bundle breaks the signature.

spctl

Checks Gatekeeper's assessment:

  • spctl --assess --type execute --verbose /Applications/AppName.app — returns "accepted" for notarized apps from known developers, "rejected" or warnings for others.

A notarized app from a recognised developer shows source=Notarized Developer ID. An older signed-but-not-notarized app shows source=Developer ID. Anything else (ad-hoc signed, unsigned) is worth investigating before launch.

Inspecting a PKG before it runs

PKG installers can do more than copy an app — they can install background helpers, launch agents, kernel extensions (rare in 2026), and command-line tools. Before running an unfamiliar PKG, inspect it.

Suspicious Package

Free Mac app from Mothers Ruin Software. Drop a .pkg onto its window and it shows every file the package will install, where each goes, who owns it, what pre/post-install scripts run, and the package's code signature. The best non-CLI way to know exactly what a PKG does.

Command-line inspection

  • pkgutil --check-signature path/to/installer.pkg — checks the package signature and lists the certificate chain.
  • pkgutil --expand path/to/installer.pkg /tmp/expanded — extracts the package contents without installing. You can browse the Payload and Scripts folders inside.
  • xar -tf installer.pkg — lists the contents.

Look for scripts in the Scripts folder. They are shell scripts that run with admin privileges during install. Read them. Reputable installers' scripts are short and obvious; suspicious ones often have obfuscated payloads or download additional binaries from URLs.

VirusTotal — the second opinion

VirusTotal scans a file against 70+ antivirus engines and provides aggregated results. Use it as a second opinion for unfamiliar downloads:

  • Visit virustotal.com and upload the file, or paste the URL.
  • Wait for the scan to complete.
  • Look at the Detection tab — number of engines that flagged the file.
  • Check Details for the file's SHA-256 (cross-reference with the developer's published checksum if available).
  • Check Behavior for what the file does at runtime in a sandbox.
  • Check Community for comments from other users.

How to interpret results: 0-1 detections for a new file from a known developer is usually fine (false positives happen, especially with obfuscated installers or apps using less common code-signing). 5+ detections on a file from a smaller developer is a strong red flag. Always look at which engines flagged the file — well-known engines (Kaspersky, ESET, BitDefender, Sophos) carry more weight than obscure ones.

Privacy note: VirusTotal stores uploaded files. Do not upload anything containing personal data, internal company tools, or proprietary files. For sensitive files, scan the URL or use the CLI scanner from a security vendor instead.

Verification workflow at a glance

StepToolTimeWhen to use
HTTPS + correct URLBrowser5 secAlways
SHA-256 checksumshasum -a 25630 secWhen developer publishes one
GPG signaturegpg --verify2 minSecurity-critical apps
codesign + spctlbuilt-in30 secAny unfamiliar app
Suspicious PackageGUI1 minAny PKG installer
VirusTotalweb upload2 minFiles from unfamiliar sources

A real verification example

Say you downloaded WireGuard.dmg from the official WireGuard site. The verification steps:

  • Confirm the URL is https://www.wireguard.com and not a typosquat.
  • Compute the checksum: shasum -a 256 ~/Downloads/WireGuard.dmg.
  • Compare to the value on the WireGuard download page.
  • After mounting and dragging the .app to Applications: codesign -dvv /Applications/WireGuard.app. Look for "Authority=Apple Root CA" and a TeamIdentifier you can verify.
  • spctl --assess --type execute --verbose /Applications/WireGuard.app. Expect "accepted" and "source=Notarized Developer ID."
  • Launch. Grant only the permissions WireGuard needs (Network only).

Five minutes of verification before installing a tool that handles your network traffic is a reasonable investment.

When verification fails

If a verification step fails — checksum mismatch, signature invalid, spctl rejects the app — stop and investigate before installing:

  • Re-download the file from the official source on a different network. The original download may have been corrupted in transit, or you may have been on a compromised network.
  • Check the developer's official changelog or release notes — sometimes signatures change because of certificate renewals, and reputable developers will mention it.
  • Cross-check the SHA-256 against multiple sources (developer site, official GitHub release, third-party tracker if available).
  • If the file consistently fails verification, do not install. Report it to the developer.

Conclusion

Verification is fast once you've done it a few times. For ordinary apps from known developers, Gatekeeper and XProtect already do the work — your job is to make sure the file came from the right place. For anything beyond ordinary, the four-step workflow (URL → checksum → codesign/spctl → VirusTotal when needed) takes a few minutes and removes the largest practical risks. The pattern is the same regardless of app: be sure the file is what the developer published, and be sure the developer is who you think they are.