Tutorials

How to Verify an APK’s SHA-256 Hash Before Installing (and Read a VirusTotal Report)

Springmusk Springmusk 7 min read 3 comments
Abstract illustration of a glowing shield outline surrounded by flowing data streams and hexagonal fragments on a dark blue background.

TL;DR: Before installing any sideloaded APK: compute its SHA-256 hash, compare it character-by-character against the hash the developer published, look up the hash on VirusTotal (search the hash, do not upload the file), check the signing certificate with apksigner, and sanity-check the package name and permissions. Five minutes of checks that catch tampered and repackaged APKs.

Sideloading an APK means bypassing every gatekeeper at once. Google’s own analysis found more than 90 times as much malware in sideloaded apps as in Google Play apps — and from September 30, 2026, Android starts enforcing developer verification in its first four countries, precisely because anonymous app distribution has become the malware channel of choice.

Every download page in this site’s download hub publishes a SHA-256 hash for exactly this reason: so you can prove the file you got is the file the developer released. Here is the full workflow, end to end.

What a SHA-256 hash proves — and what it doesn’t

A SHA-256 hash is a 64-character fingerprint of a file. Change a single byte and the fingerprint changes completely. Comparing the hash of your downloaded APK against the hash published by the developer proves the file was not modified in transit — no injected ad SDK, no swapped payload, no corrupted download.

What it does not prove: that the file is safe. A hash match means the file is exactly what the developer released — if the developer is malicious, the hash will match perfectly. That is why hash verification is step one of five, not the whole check.

Step 1: Compute the hash of the APK you downloaded

On Android: install Hash Droid from Google Play, choose “Hash a File”, select SHA-256, pick the APK, and tap Calculate. Copy the resulting 64-character string.

On desktop:

# Linux
sha256sum app.apk

# macOS
shasum -a 256 app.apk

# Windows (Command Prompt)
certutil -hashfile app.apk SHA256

# Windows (PowerShell)
Get-FileHash app.apk -Algorithm SHA256

All four produce the same value for the same file. Hashing is local and instant — a 100MB APK takes a couple of seconds on any modern machine.

Step 2: Compare it against the published hash

Paste both hashes into any text editor, one above the other. Every one of the 64 characters must match. Hashes are case-insensitive, but anything else — a single different character, a different length — means the file is not the one the developer released. Delete it and re-download from the official source.

A mismatch does not automatically mean malware; it can be a truncated download. But the correct response is the same: do not install it. Re-download, re-hash, and only proceed when the strings match exactly.

Where do trustworthy hashes live? On the developer’s own release pages — GitHub release notes, the project’s official download page, or a dedicated downloads section like this site’s APK hub, where each tool’s page publishes the SHA-256 of the official binary alongside a copy button. Never trust a hash pasted into a forum comment or a Telegram channel; the attacker who modified the file can just as easily modify the hash next to it.

Step 3: Look up the hash on VirusTotal — without uploading the file

VirusTotal’s web interface accepts file uploads up to 650MB, but for a hash you already computed, there is a better option: search the hash itself. Go to virustotal.com/gui/home/search, paste the 64-character hash, and search.

If the file has been seen before, you get the full existing report without uploading anything — faster, and your copy never leaves your machine. If the hash is unknown, only then consider uploading the file itself.

Reading the report:

  • Detection count. A clean report shows 0 detections across all engines. One or two detections from obscure vendors with every major vendor clean usually means a false positive — but treat it as a yellow flag, not a green light, and look for a newer report or the developer’s own statement.
  • Which vendors flagged it. Detections from several major antivirus vendors are a red flag. Check the detection labels: generic heuristic names (“Suspicious”, “Gen:Variant”) differ in weight from specific trojan families.
  • First submission date. A report first submitted years ago for a file whose hash matches today’s release means the file has a long, stable history. A report created yesterday for a supposedly old release is suspicious.
  • Community comments. VirusTotal’s community section surfaces false-positive reports and analyst notes. Read them before concluding.

VirusTotal is an aggregator, not a verdict. It tells you what dozens of engines think; you still decide. But a matching developer hash plus a clean multi-engine report is the strongest pre-install evidence available.

Step 4: Check who signed it with apksigner

Android requires every APK to be signed, and updates must carry the same signature as the original install — otherwise Android refuses with a signature conflict. The apksigner tool ships with Android SDK build-tools:

apksigner verify --print-certs app.apk

The output lists the signer’s certificate digests (SHA-256 and SHA-1) and the signature scheme versions used. What to do with them:

  • When updating an app you already have installed, the certificate digest must be identical to the previous version’s. A different digest on an “update” of the same package name means a different signer — do not install it.
  • Debug-signed certificates (CN=Android Debug) on an app claiming to be a production release are a red flag: legitimate releases are signed with the developer’s release key.

This check matters most for updates. A repackaged APK with injected malware cannot be signed with the original developer’s key, so it can never pass as an update to the legitimate app — but it can pass as a fresh install if you never check.

Step 5: Sanity-check the package name and permissions

Two quick static checks before installing:

aapt dump badging app.apk | grep package

Confirm the package name matches the app it claims to be — a file claiming to be WhatsApp with a package name like com.randomdeveloper.whatsappclone is fake regardless of everything else.

Then review the permissions list in the same aapt output. A flashlight app requesting GPS and SMS access, or a wallpaper app wanting microphone permission, does not add up. Permissions are declared, not hidden — read them.

The full checklist at a glance

Check What it catches What it misses
Compare SHA-256 against the published hash Tampered, corrupted, or substituted files Malware the developer shipped themselves; wrong-but-trusted source
VirusTotal hash lookup Known malware families and flagged variants Brand-new malware with no signatures; targeted payloads
apksigner certificate check Repackaged “updates” signed by a different key Fresh installs of malicious apps signed by their own key
Package name and permissions review Cloned apps with fake names; over-privileged apps Malware that needs no suspicious permissions

No single check is sufficient; together they close the realistic attack paths against sideloaded APKs. And note what none of them replace: getting the APK from the developer’s official source in the first place.

Key takeaways

  • A matching SHA-256 hash proves the file is exactly what the developer released — nothing more. It is necessary but not sufficient.
  • Search the hash on VirusTotal instead of uploading the file: same report, no upload, works for any file size.
  • One or two obscure-vendor detections with all major vendors clean is usually a false positive — but verify before installing, don’t assume.
  • Use apksigner to compare signing certificates when updating: a different signer on the same package name means a repackaged file.
  • The five-minute workflow is: hash, compare, VirusTotal lookup, certificate check, package and permissions review — in that order.

References

3 comments

Join the discussion

Your email address will not be published. Required fields are marked *