If you are currently using or planning to adopt key rotation by replacing the app signing key from key A to key B, please make sure to check the following to ensure the signature identity verification feature works properly.
Scenario: Replacing an app signed with key A to key B
1. Initial release (using only key A)
- Apply AppSecurity (register and bundle key A)
- Sign with key A and distribute/install
- At runtime, verify the signature based on key A
2. When delegating distribution to key B
- Apply AppSecurity (register and bundle both key A and key B)
- Sign the APK with key A + key B + key lineage (signature certificate lineage)
- The signature key observed at runtime depends on the deviceโs Android version (see "Behavior by OS version" below)
Example commands for key rotation
First, create a lineage file using the rotate subcommand of apksigner, then use the new key (B) and the lineage file together in the sign command to sign.
1) Create a lineage file
apksigner rotate --out lineage.bin \
--old-signer --ks A.keystore \
--new-signer --ks B.keystore
2) Sign with the new key (including the lineage file)
apksigner sign --ks B.keystore \
--next-signer --ks C.keystore \
--lineage lineage.bin \
app-release.apk
--next-signeris an option used when you plan to rotate again to another key (C) in the future; if you are only rotating to key B this time, you can omit it. The v1/v2 blocks of the signed APK include only the original signerโs (key A) signature, while the v3 (and v3.1) blocks contain the signature of key B and the lineage proof that "trust from key A is inherited by key B." Note that keys A and B do not sign side-by-side in the same block.
Behavior by OS version: What exactly "differs depending on install/update" means
For the same APK and the same Android version, the signature key observed at runtime is the same whether it is the initial install or an update. What actually depends on whether it is an install or update is the OSโs permission to install (if signed only with key B without a lineage file, updates to an app previously installed with key A will be rejected due to signature mismatch). The Android version determines which key is recognized as valid at runtime.
- Android 8.1 and below (API 27 and below): Does not support APK Signature Scheme v3, does not understand lineage (rotation) extensions, and always verifies using the original signer (key A) in the v1/v2 blocks.
- Android 9 and above (API 28 and above): Supports v3, recognizes lineage, and verifies with key B. (See the note about v3.1 below)
AppSecurity only verifies whether the signature key information actually read by the OS is registered and bundled. In other words, both keys A and B must be registered to avoid false positives of signature tampering on devices with any Android version.
Caution: Differences due to APK Signature Scheme v3.1 and build-tools version
The apksigner included in Android SDK build-tools 33 and above places the rotated (new) key information in the v3.1 block (for Android 13 / API 33 and above only) by default unless specified otherwise. In this case:
- Android 9 to 12L (API 28 to 32): Observed as key A (original signer) based on the v3 block
- Android 13 and above (API 33 and above): Observed as key B (rotated signer) based on the v3.1 block
Therefore, it cannot be assumed that "key B is always observed on API 28 and above." The actually observed key depends on the apksigner version and options. To have key B observed on devices with API 28โ32, specify a lower API level with the --rotation-min-sdk-version option during signing.
apksigner sign --ks B.keystore \
--lineage lineage.bin \
--rotation-min-sdk-version 28 \
app-release.apk
If it is difficult to precisely distinguish and handle these option and version differences, the safest approach is to register both key A and key B in AppSecurity. If you encounter an issue where the app signing key appears as key A on devices with API 28 and above, it is usually due to this v3/v3.1 block difference.
Must-check items
If you are using a key rotation scenario, to ensure stable operation across all platforms, the app must be signed with both key A and key B together.
It is safest to continue registering and maintaining both key A and key B even after key rotation. If you unregister the previous key (A) after the transition period ends, older OS versions or devices that have not yet updated will still verify with key A, which risks false positives for signature tampering. Do not arbitrarily unregister key A.
Checklist
- [ ] Are you using key rotation?
- [ ] If yes, have you registered both key A and key B in AppSecurity? (and continue maintaining them after rotation)
- [ ] Are you distributing builds properly signed with key A, key B, and lineage?
- [ ] Are you aware that the observed key may differ by OS version depending on build-tools version and
--rotation-min-sdk-versionsettings?
If any of the above items are not met, normal service may be blocked in some user environments (specific OS versions, install/update combinations), so please verify in advance.