Android APK Signature Verification Mechanisms and Implementation
Overview
The Android signature verification system has evolved through multiple generations with distinct approaches for ensuring APK integrity. Modern Android systems prioritize newer signature schemes when verifying packages.
Systems running Android 9.0 and above first check for V3 signatures. If present, they validate using the V3 method—successful validation allows installation while failure rejects it. If no V3 signature exists, the system checks for V2, then falls back to V1 if necessary.
V1 Signature Scheme
The V1 approach adds a META-INF directory containing three critical files:
MANIFEST.MF: Stores digests for every file in the APK*.SF: Contains the digest ofMANIFEST.MFplus digest information for each entry within the manifest*.RSA: Holds the signature of*.SFand the public key certificate
For example, examining Xiaomi's universal remote APK reveals these structures in the META-INF folder. The MANIFEST.MF file stores base64-encoded SHA256 digests paired with filenames.
The .SF file extends beyond MANIFEST.MF by including the manifest's digest and calculating digests for each module within the manifest. Modules can be identified by their hexadecimal ending 0D0A0D0A, representing double line breaks.
The .RSA file is a binary encoded using ASN.1 DER rules in PKCS#7 format. Extract certificate information using:
openssl pkcs7 -inform DER -in <path-to-RSA-file> -text -noout -print_certs
Security Limitations of V1
The V1 scheme provides insufficient integrity protection. Modifications to data blocks not covered by the original file verification can bypass this security layer entirely.
V2 Signature Scheme
APK Signature Scheme v2 implements a whole-file signing approach that detects all modifications to protected APK sections.
The APK Signing Block consists of these components:
| Offset | Bytes | Description |
|---|---|---|
| @0 | 8 | Length of this block (excluding this field) |
| @8 | n | Set of ID-value pairs |
| @-24 | 8 | Block length (matches first field) |
| @-16 | 16 | Magic number "APK Sig Block 42" |
The ID-value pair block with ID = 0x7109871a stores V2 signature information. Teams like Meituan have leveraged custom IDs for generating distribution packages.
The value section contains V2 signature data, supporting one or multiple signer entries. The content structure includes digest information and certificates.
Digest Calculation Process
Digest computation operates exclusively on raw zip content:
- Block Division: Split each section into 1MB chunks (last chunk may be smaller) to enable parallel digest calculation
- Chunk Digest Calculation: Compute digest for each chunk using
0xa5 + chunk_length + chunk_contentformat - Aggregate Digest: Combine final digest using
0x5a + chunk_count + chunk_digestsformat
Rollback Prevention
To prevent attackers from removing V2 signatures, APKs with V2 signatures that also contain V1 signatures must include the X-Android-APK-Signed attribute in their META-INF/*.SF files.
V3 Signature Scheme
V3 signatures use ID-value storage with ID 0xf05368c0. This design mirrors V2 but adds support for SDK version ranges and proof-of-rotation structures.
V3 was specifically developed for Android 9's APK key rotation feature, extending V2 capabilities with additional data blocks for key rotation information. The structure builds upon V2 while incorporating new fields for signature key updates.
V4 Signature Scheme
V4 signatures support ADB incremental APK installations. Incremental updates utilize BSDiff algorithms to create patches based on bytecode differences between APK versions. The server generates patch files, and clients combine installed APKs with patches to create updated versions, reducing download times and improving update efficiency.
V4 uses different signing mechanisms compared to V2 and V3 implementations.
Practical Signing Operations
Two primary tools handle APK signing: jarsigner and apksigner.
jarsigner: JDK-provided tool for JAR package signing located atJDK/bin/jarsignerapksigner: Google's dedicated Android APK signing tool found atAndroid SDK/build-tools/version/apksigner
Both tools require keystore files for operation.
Keystore Generation with Keytool
Generate keystores using keytool:
keytool -genkey -keyalg RSA -keystore output_keystore_name.keystore
Complete the information prompts to generate the keystore. Alternatively, specify an alias:
keytool -genkey -keyalg RSA -keystore demo1.keystore -alias my_alias
Jarsigner Usage
Sign with the command:
jarsigner -keystore keystore_path input.apk key_alias
Key parameters include:
-digestalg: Digest algorithm specification-sigalg: Signature algorithm specification
Apksigner Usage
apksigner sign --ks keystore_path --ks-key-alias alias_name target.apk
By default, apksigner enables both V1 and V2 signing. Disable specific schemes using:
--v1-signing-enabled false--v2-signing-enabled false