Every Android app is trusted because of one private key, and if that key is lost, leaked or weakly protected, attackers can ship updates your users' phones will accept or repackage your app under your name. APK signing is the mechanism Android uses to tie an app package to its developer and to detect any change to the package after it was signed. Android has four signature schemes (v1 to v4, plus the v3.1 refinement), two kinds of signing key when Google Play signs on your behalf, and a lineage format for rotating keys. This guide explains what each scheme protects, how verification and key rotation work, how to check a signature with apksigner, and how defenders use signing certificates to spot modified and repackaged apps. It is written for mobile developers, release engineers and security teams who review Android apps. Broader app hardening is in the Android App Security Guide, and the risks of installing apps from outside a store are in APK sideloading.
Key takeaways
- A signature proves continuity, not goodness. Android uses the signing certificate to decide whether an update comes from the same developer as the installed app; it does not say the app is safe.
- v1 alone is weak. JAR signing leaves ZIP metadata unprotected; schemes v2 and later sign the whole file, so any change, including to ZIP metadata, breaks the signature.
- Keys can now rotate. Scheme v3 (Android 9) added a proof-of-rotation lineage, and v3.1 (Android 13) lets you target rotation at newer platform versions so older devices keep the original signer.
- Play App Signing splits the risk. Google holds the app signing key; you hold an upload key that can be reset if it is lost or compromised.
- Certificate digests are your integrity anchor. Compare the SHA-256 digest of the signing certificate, from
apksigner verify --print-certsor the Play IntegritycertificateSha256Digest, against the value you expect.
What it is
APK signing is the process of attaching a cryptographic signature and an X.509 certificate to an Android package (APK) so the platform can verify who built it and that it has not been altered. The certificate does not need to come from a public certificate authority: Android apps are normally signed with a self-signed certificate, and trust comes from consistency. The first install of an app records its signing certificate; every later update must be signed by the same key, or by a newer key that the original key has vouched for through rotation. If the signature does not match, the update is refused.
The private key is therefore one of the most valuable non-human credentials a mobile team owns. Anyone holding it can publish updates that installed copies will accept. That is why the key belongs in a hardware-backed or managed key store, not in a repository or a build agent's home directory. See the Code Signing Security Guide for the general discipline and the Java Keystores Guide for the keystore files Android tooling uses.
How it works
The signature schemes
| Scheme | Introduced | What is signed | Notes |
|---|---|---|---|
| v1 (JAR signing) | Since the first Android release | Individual ZIP entries, via META-INF manifest files | Does not protect some parts of the APK, such as ZIP metadata; the verifier must decompress and parse many untrusted structures |
| v2 | Android 7.0 | The whole APK, signature stored in an APK Signing Block | Any modification, including ZIP metadata, invalidates the signature; faster install verification |
| v3 | Android 9 | As v2, with extra information in the signing block | Adds key rotation through a proof-of-rotation lineage |
| v3.1 | Android 13 | As v3, in a new block ID | Rotation can target a minimum SDK version; Android 12 and lower ignore the v3.1 block and use the original signer |
| v4 | Android 11 | A Merkle hash tree over every byte of the APK, in a separate .apk.idsig file | Supports streaming installs (adb install --incremental); follows the fs-verity tree structure; always needs a v2 or v3 signature as well |
Android's guidance is to sign with all applicable schemes for maximum compatibility, in order v1, then v2, then v3, because platforms older than Android 7.0 ignore v2 and later signatures and rely on v1. If your minSdkVersion is 24 or higher, v1 is not needed for installation. Stripping protection is built in: an APK that was v2-signed but has had its v2+ signature removed is rejected, because the v1 signature records that the APK was v2-signed.
Key rotation and lineage
Scheme v3 lets an app change its signing key as part of an update. The proof-of-rotation structure is a singly linked list ordered from the oldest certificate (the root) to the newest, where each certificate signs the next one. It sits inside the signed data of the v3 signer, so the current key protects the whole history. Each node carries capability flags that say whether apps signed by an older certificate are still trusted for particular operations, such as signature-level permissions. The format supports one signing key at a time, not several.
AOSP does not recommend key rotation for Android 12 (API level 31) and earlier. Scheme v3.1 fixes that by letting the developer set a minimum SDK version for the rotated key: the original signer signs the v3 block for older devices, and the rotated signer signs the v3.1 block that only Android 13 and later read. From Android 13, checkSignatures understands the lineage and returns the newest signature.
Play App Signing and app bundles
| Key | Who holds it | Used for | If compromised or lost |
|---|---|---|---|
| App signing key | Google, in its Key Management Service infrastructure | Signs the APKs delivered to users from your app bundle | Request a key upgrade: the new key signs installs and updates on Android 13 and later, the old key continues for earlier versions |
| Upload key | The developer | Signs the app bundle or APK uploaded to the Play Console; Google verifies it with the upload certificate | Request an upload key reset in the Play Console; the app signing key is unaffected |
| Self-managed signing key | The developer | Signs APKs distributed directly or outside Play | Rotate with a v3 or v3.1 lineage; without rotation, existing installs cannot be moved to a new key |
Play App Signing is required to distribute through Google Play for apps created after August 2021; older apps may continue to distribute self-signed APKs, but apps that do not opt in cannot use Android App Bundles, Play Feature Delivery or Play Asset Delivery. Once enrolled, you cannot retrieve a copy of the app signing key. Android's documentation recommends keys valid for at least 25 years, and Google Play requires a validity period ending after 22 October 2033. Use different keys for app signing and upload, and separate strong passwords for the keystore and each key.
Verifying a signature with apksigner
- Align before signing: run
zipalignbeforeapksigner sign; any change after signing invalidates the signature. - Sign:
apksigner sign --ks release.jks app.apk, or--key(PKCS #8) with--cert(X.509). Add--lineagewhen signing with a rotated key and--v4-signing-enabledto produce the.idsigfile. - Verify:
apksigner verify -v --print-certs app.apkreports which schemes verified and prints each signing certificate's digests.--min-sdk-versionchecks that the signature will verify on the oldest platform you support. - Compare the digest: check the SHA-256 certificate digest against the value recorded in your release register or Play Console, not against a value taken from the APK being checked.
- Rotate when needed:
apksigner rotate --out lineage --old-signer --ks old.jks --new-signer --ks new.jkscreates or extends the lineage file.
Why it matters
Detecting repackaged and modified APKs
A repackaged app is a legitimate APK that someone has unpacked, modified (adding malware, removing licence checks or ads, or injecting a hooking framework) and re-signed with their own key. They cannot re-sign with yours, so the certificate digest changes. MITRE ATT&CK for Mobile describes the related technique of giving malicious apps the name, icon or package name of trusted apps (T1655.001 Match Legitimate Name or Location). Defenders use signing data at several points:
- Server side: the Play Integrity API returns
appRecognitionVerdict.PLAY_RECOGNIZEDmeans the app and certificate match what Google Play distributes;UNRECOGNIZED_VERSIONmeans the certificate or package name does not match Play records. ThecertificateSha256Digestarray lets your backend compare the signing certificate with your own. See Mobile App Attestation. - Fleet side: mobile threat defence and MDM tools compare installed package names with expected signing certificates, catching an app that claims a bank's package name but carries a different certificate. See the Mobile Threat Defense Buyer's Guide.
- Triage: analysts run
apksigner verify --print-certson a suspicious APK and compare it with the official build; a mismatch confirms modification even before any code analysis. - App links: Android App Links trust is declared by publishing the signing certificate's SHA-256 fingerprint on your domain, so a key change must be reflected there. See the Mobile Deep Link and App Link Security Guide.
Decision guidance
| Situation | Recommended approach | Trade-off |
|---|---|---|
| New app published on Google Play | Play App Signing with a separate upload key held in a managed key store | You cannot export the app signing key; distribution outside Play needs its own plan |
| App distributed outside Play (enterprise, alternative stores) | Self-managed key in an HSM or cloud KMS; sign v2 and v3; plan a v3.1 lineage before you need it | Full responsibility for key custody and backup |
| Suspected key compromise, Play app | Upload key reset if only the upload key leaked; key upgrade if the app signing key is affected | Key upgrade only protects Android 13 and later installs |
| Weak legacy key (short RSA or SHA-1 era certificate) | Rotate with v3.1 targeting Android 13 and later | Devices on Android 12 and earlier keep the old key |
| Small team without HSM | Play App Signing, upload key in a password manager or CI secret store with restricted access | Upload key reset is your recovery route |
Detection and measurement
- Log every signing operation in CI with the job, commit and key alias, and alert on signing outside the release pipeline.
- Monitor Play Integrity verdicts for the share of
UNRECOGNIZED_VERSIONand unexpected certificate digests reaching your API. - Scan repositories and artefact stores for keystore files (
.jks,.keystore,.p12) andsigningConfigspasswords. See the Secrets in mobile apps guide.
Useful metrics: releases signed outside the pipeline (target 0); signing keys stored outside an HSM or KMS (target 0); percentage of API traffic from PLAY_RECOGNIZED builds; time from a leaked upload key to reset (target under 24 hours); and the number of copycat packages with your app name but a foreign certificate found by store monitoring.
Common misconceptions
- "Signed means safe": malware is signed too. A signature only proves the package has not changed since its signer signed it.
- "v1 is enough because the app installs": it installs, but ZIP metadata is unprotected and the v1 verifier has a larger attack surface. Sign with v2 or later.
- "We can just switch keys": without a v3 or v3.1 lineage, or a Play key upgrade, installed apps will refuse updates signed with a new key.
- "Google has our key, so key security is Google's problem": the upload key still authenticates every release you submit; a stolen upload key and Play Console access together allow a malicious release.
- "The certificate expiry date stops the app working": Android verifies signatures for update continuity, and Google Play itself requires validity ending after 22 October 2033, so plan long-lived keys from the start.
- "Checking the signature inside the app is sufficient": an attacker who repackages the app can remove an in-app check. Verify on the server with Play Integrity, as the OWASP MASVS resilience guidance treats client checks as defence in depth only.
Related concepts
| Concept | Relation to APK signing | Framework reference |
|---|---|---|
| Code integrity and authenticity | Signed components and code authentication | NIST SP 800-53 SI-7, SI-7.15, CM-14 |
| Component authenticity in the supply chain | Checking certificate digests before distribution | NIST SP 800-53 SR-11 |
| Code signing as a mitigation | Enforcing signed binaries | MITRE ATT&CK M1045 Code Signing |
| Masquerading apps | Copycat apps using trusted names or package names | MITRE ATT&CK for Mobile T1655.001 |
| Resilience and anti-tampering | Runtime tamper and integrity checks | OWASP MASVS-RESILIENCE |
- Debug signing: builds signed with the SDK debug key must never reach users; the SDK creates the debug keystore automatically with a well-known default password. See Android Platform Tools and ADB.
- Key file formats: keystores, PKCS #12 and PEM files hold the signing key. See Certificate and Key File Formats.
- Supply chain: see OWASP Mobile Top 10 M2 for build pipeline risks.
Common failure patterns
- Keystore committed to source control with its password in
build.gradleorgradle.properties. Hard-coded secrets in mobile apps are common, as the Mobile Apps Hard-Coded AWS Keys 2022 research showed for cloud keys. - Same key for upload and app signing, so a leaked CI secret is also the key every user trusts.
- No backup of a self-managed key, leaving the team unable to ship updates after a laptop failure.
- Stolen signing keys used to sign malware: the NVIDIA code signing certificates theft shows how leaked signing material is reused against everyone who trusts it.
- Rotation attempted without v3.1, breaking updates for users on Android 12 and earlier.
Practitioner checklist
- Enrol Play apps in Play App Signing with an upload key separate from the app signing key.
- Store self-managed and upload keys in an HSM, cloud KMS or restricted CI secret store, never in a repository.
- Sign with v2 and v3 at minimum; add v1 only if
minSdkVersionis below 24. - Record each signing certificate's SHA-256 digest in a release register and check it in CI with
apksigner verify --print-certs. - Verify Play Integrity
appRecognitionVerdictand certificate digests on the server for sensitive APIs. - Plan rotation with a v3.1 lineage, and document the upload key reset and key upgrade process.
- Scan repositories and artefacts for keystore files and signing passwords.
- Monitor stores for copycat apps carrying your name with a different certificate.
Standards and references
- Android Open Source Project: Application signing
- Android Open Source Project: APK Signature Scheme v3
- Android Open Source Project: APK Signature Scheme v3.1
- Android Open Source Project: APK Signature Scheme v4
- Android Developers: apksigner
- Android Developers: Sign your app
- Android Developers: Play Integrity API integrity verdicts
- OWASP: Mobile Application Security Verification Standard
Related NHI Mgmt Group resources: Android App Security Guide · Code Signing Security Guide · APK sideloading · Mobile App Attestation