Android 13 supports APK Signature Scheme v3.1, an improvement on the existing APK Signature Scheme v3. The v3.1 scheme addresses some of the known issues with APK Signature Scheme v3 regarding rotation. In particular, the v3.1 signature scheme supports SDK version targeting, which allows rotation to target a later release of the platform.
The v3.1 signature scheme uses a block ID that isn't recognized on Android 12 or lower. Therefore, the platform applies the following signer behavior:
- Devices that run Android 13 or higher use the rotated signer in the v3.1 block.
- Devices that run older versions of Android ignore the rotated signer and instead use the original signer in the v3 block.
Apps that haven't yet rotated their signing key don't require any additional action. Whenever these apps choose to rotate, the system applies the v3.1 signature scheme by default.
v3.1 signing block
The v3.1 signing block will have the same contents as the v3 signing block, but with the new block ID these signatures will only be recognized on devices running Android 13 and later. This allows apps to safely rotate their signing keys without needing to worry about multi-target APKs as the original signer can be used to sign the APK in the v3 signing block and the rotated signer in the v3.1 signing block. This also allows the platform to reuse all existing verification codes for the v3 signing block when verifying a v3.1 signature.
By default, the
apksig library will use the
v3.1 signing block whenever a rotated key and lineage is provided in the signing
config. If an app's
minSdkVersion is less than
Android 13 and a rotated key is being used, the original signing key must be
specified as well so that it can be used to sign the APK in the v3 signing
block. This is similar to the current behavior where the original signer is
required if the APK targets a version earlier than Android 9.
To support targeting key rotation starting from a particular SDK version,
apksig library will expose new APIs that will allow
setting a minimum SDK version for rotation If an SDK version less
than Android 13 is specified as the minimum version for rotation support then
the original v3 block will be used. The v3.1 signing block is only used in the
presence of rotation where the minimum SDK version for rotation is set to
Android 13 and later. The v3 signing block will have a new attribute for rotation
minimum SDK version stripping protection.
|APK Includes Lineage||Value of rotation-min-sdk-version||v3 signing block||v3.1 signing block|
|No||Default or any value (represented by x below)||Signed with original signer, targeting Android 9 and later||Not present|
|Yes||Default||Signed with original signer, targeting Android 9 through 12L||Signed with rotated signer, targeting Android 13 and later|
|Yes||x < 33 (Android 13)||Signed with rotated signer, targeting Android 9 and later||Not present|
|Yes||x >= 33 (Android 13)||Signed with original signer, targeting Android 9 - (x-1)||Signed with rotated signer, targeting x+|
The following rotation-related problems have been resolved in the platform:
Android 12 fixes
- The platform would only grant a signature permission to a requesting app if either app's current signer is in the signing lineage, or is the current signer, of the other app; this prevents granting a signature permission to a requesting app if the two apps follow signing key best practices and rotate to different signing keys.
- The platform's APK rollback feature could not rollback an APK that just had its signing key rotated unless the previous key in the signing lineage had the rollback capability, but this capability defeats the purpose of rotation as it allows a new package update to be signed by the previous signing key and rolling back the rotated key.
- An APK signed with only the rotated key and later updated with an APK signed with the original key and the rotated key in the lineage will only show the rotated key in the lineage on devices running Android 11 and earlier.
Android 11 fixes
PackageManager#checkSignatureswas not properly updated to check the original signing keys of two packages. This broke instrumentation for apps using a rotated signing key with the instrumentation APK using the original signing key.
- Packages under a
sharedUserIdshare their signing lineage. Whenever an app with an updated signing lineage is installed or updated in a
sharedUiserIdthe lineage of that app replaced the shared lineage for the
sharedUserId(that is, if an app's signing lineage were A -> B, and an app is updated in the
sharedUserIdwith lineage B -> C, then the
sharedUserIdlineage would be replaced with B -> C). Similarly capabilities of a previous signer in the lineage could not be updated unless the signing lineage were changed.
The v4 signature scheme uses the signing config provided to apksigner; in the case of multiple signing configs provided for rotation, the latest rotated signing config is used. Prior to the introduction of v3.1, v3 only included this latest rotated signing config, so v4 was able to use this config as is; with this the v4 signature scheme was able to support rotation since it used the rotated signing key in its SigningInfo. While the v4 SigningInfo does not include the full signing lineage, it is able to pull this from the v3 signing block to allow the platform access to the lineage for any signature queries. When v3.1 is in use to target rotation for the provided rotation-min-sdk-version, the generic v3 config will include both the original signing config as well as the latest rotated signing config. An extension of the v4 signature scheme has been created that includes additional signing info blocks for each of the signing configs from the v3.1 block.
To test your implementation of v3.1, run the
PkgInstallSignatureVerificationTest.java CTS tests in
For more information about testing, check out the verification section in v3.