I wanted to know more about apk signature verification and took to the MagicEarth App as an example as the App came up in a forum question. I fetched one of the prebuilt apks in the commit history and run
~$ apksigner verify --verbose --print-certs magicearth.apk Verifies ... Signer #1 certificate DN: CN=ROUTE 66, OU=ROUTE 66 Switzerland GmbH, O=ROUTE 66 Switzerland GmbH, L=Brasov, ST=Romania, C=RO Signer #1 certificate SHA-1 digest: 3705ba93d86f9566cdb440977e65c8df660514ae
In the first line
apksigner verfies successfully the integrity of the apk, attesting that the checksums kept in summary files that the signature covers are indeed the same. If a file in the archive is altered and the attacker is not in the possession of the original signing private key and uses another one, the signed certificate will have another fingerprint. Also, if an update Apk doesn’t match the signature fingerprint of the already installed app ID, an installation is denied. So while there’s no protection for the first time install, there is for the update.
The next thing I want to know is if the signing certificate really does belong to the Organisation it claims to come from. Without an authority like the Google Play Publisher API telling me or the publisher itself doing it (as Signal.org or F-Droid Repos do), some mirrors are looking at past certificates used for the App. This can be a valid heuristic to decide on the trustworthiness, but obviously has shortcomings for releases after a private key has been compromised. A public notary would be preferable.
Services like androidobservatory.org check over time what certificate is used for a specifid app id. You can compare this across mirrors for the MagicEarth sha1 fingerprint (
3705B[...]14AE) they’re identical for this current sample: aapks.com, apkpure.com (info icon), apkmirror.com (click “verified safe to install”). And Cleanapk:
curl "https://api.cleanapk.org/v2/apps?action=search&keyword=com.generalmagic.magicearth&by=package_name" | jq # look for an object to search for curl -s --globoff "https://api.cleanapk.org/v2/apps?action=app_detail&exact_arch=false&id=5bef39e54ecab403b15e9cb7&architectures=[arm64-v8a]" | jq | grep signature "signature": "3705ba93d86f9566cdb440977e65c8df660514ae",
To have some assurance after the fact one can also compare signing certificate fingerprints of installed packages with Checkey. It will show a sha1
3705B[...]14AE for the Magicearth App.