Kurz gesagt. Android prüft je nach Gerät eines von mehreren Signaturformaten: v1 (JAR-Signatur, pro Datei, für Android 6 und älter), v2 (Signatur über die ganze Datei im APK-Signaturblock, Android 7.0), v3 (v2 plus eine Rotationskette als Proof of Rotation, Android 9), v3.1 (Rotation, die nur für Android 13 und neuer gilt), v3.2 (eine hybride Signatur aus klassischem Verfahren plus ML-DSA, Android 17) und v4 (eine separate .idsig-Datei für inkrementelle Installationen, Android 11). Apps, die auf API-Level 30 oder höher ausgerichtet sind, müssen mit v2 oder einem neueren Verfahren signiert sein. Updates müssen mit demselben Schlüssel signiert sein oder mit einem Nachfolger aus der Rotationskette der App. Damit ist der Signaturschlüssel die Identität der App, ihr ganzes Leben lang: Lass ihn Google Play verwahren (Play App Signing), behalte selbst nur den Upload-Schlüssel und prüfe Releases mit apksigner verify -v --print-certs.
Für die Versuche haben wir apksigner aus den Android SDK build-tools 37.0.0 verwendet (das Tool meldet sich als Version 0.9), unter Java 25.0.4.1 in eclipse-temurin:25.0.4.1_1-jdk-noble. Als Beispiel dient das APK des F-Droid-Clients, so wie es am 22. Oktober 2026 von f-droid.org heruntergeladen wurde; alle anderen Schlüssel wurden für diesen Artikel erzeugt.
Die Verfahren
| Verfahren | Seit | Wo | Was es hinzufügt |
|---|---|---|---|
| v1 | Android 1.0 | META-INF/*.SF, *.RSA/*.EC | JAR-Signatur: ein Hash pro ZIP-Eintrag; die ZIP-Metadaten sind nicht abgedeckt |
| v2 | Android 7.0 (API 24) | APK-Signaturblock, ID 0x7109871a | Signatur über die ganze Datei außer dem Block selbst |
| v3 | Android 9 (API 28) | ID 0xf05368c0 | v2 plus unterstützter SDK-Bereich und eine Rotationskette (Proof of Rotation) |
| v3.1 | Android 13 (API 33) | eine neue Block-ID | Rotation, die nur auf Android 13 und neuer greift |
| v3.2 | Android 17 (API 37) | ID 0x70e1c89f | Genau zwei Signierer, ein klassischer und ein Post-Quanten-Signierer, beide werden geprüft |
| v4 | Android 11 (API 30) | app.apk.idsig neben dem APK | Merkle-Baum über das APK für adb install --incremental; braucht v2 oder v3 |
Das APK Signature Scheme v2 „behandelt die APK-Datei als Blob und prüft die Signatur über die gesamte Datei“, daher „macht jede Änderung am APK, auch eine Änderung der ZIP-Metadaten, die APK-Signatur ungültig“ (AOSP). Außerdem ist v2 schneller: Das Gerät muss nicht mehr jeden Eintrag dekomprimieren, um ihn zu prüfen. v1 dient nur noch Geräten vor Android 7.0; ein APK mit einer minSdkVersion von 24 oder höher braucht es nicht, und apksigner lässt es weg. Eine entfernte v2-Signatur lässt sich nicht dadurch verbergen, dass v1 erhalten bleibt: APKs mit v2-Signatur, die zusätzlich mit v1 signiert sind, tragen in ihren .SF-Dateien das Attribut X-Android-APK-Signed, das die v1-Signatur abdeckt. Verifizierer müssen ein APK ablehnen, dem die Signatur für ein Verfahren fehlt, das es selbst ankündigt.
Seit Android 11 gilt: „Apps, die auf Android 11 (API-Level 30) ausgerichtet sind und derzeit nur mit dem APK Signature Scheme v1 signiert sind, müssen jetzt auch mit dem APK Signature Scheme v2 oder höher signiert werden“ (Verhaltensänderungen).
Die Ausgabe von apksigner verify lesen
apksigner verify -v --print-certs prüft jedes im APK enthaltene Verfahren für den SDK-Bereich, den das APK unterstützt, und gibt die Signierer aus. Für den veröffentlichten F-Droid-Client sieht das so aus (Ausgabe auf die Zeilen zu Verfahren und Signierern gefiltert):
Verifies
Verified using v1 scheme (JAR signing): false
Verified using v2 scheme (APK Signature Scheme v2): true
Verified using v3 scheme (APK Signature Scheme v3): true
Verified using v3.1 scheme (APK Signature Scheme v3.1): false
Verified using v3.2 scheme (APK Signature Scheme v3.2): false
Verified using v4 scheme (APK Signature Scheme v4): false
Verified for SourceStamp: false
Number of signers: 1
V3.0 Signer: certificate DN: CN=Ciaran Gultnieks, OU=Unknown, O=Unknown, L=Wetherby, ST=Unknown, C=UK
V3.0 Signer: certificate SHA-256 digest: 43238d512c1e5eb2d6569f4a3afbf5523418b82e0a3ed1552770abb9a9c9ccab
V3.0 Signer: key algorithm: RSA
false bei v1 ist kein Fehler: Die App setzt mindestens SDK 24 voraus, v1 ist also überflüssig. Der Digest des Zertifikats ist der Wert, der den Signierer der App identifiziert: F-Droid veröffentlicht für seinen Client genau 43238d51…a9c9ccab auf seiner Seite zu den Signaturschlüsseln, und Android vergleicht den Signierer bei jedem Update. Eine Vertrauenskette gibt es nicht: APK-Zertifikate sind meist selbstsigniert, und die Regeln der v2-Prüfung verlangen, dass die SubjectPublicKeyInfo des ersten Zertifikats zum Signaturschlüssel passt; einen Schritt für Aussteller oder Gültigkeitszeiträume enthalten sie nicht (v2). Dieses Zertifikat wurde 2010 ausgestellt.
Wenn wir eine Kopie mit unserem eigenen P-256-Schlüssel neu signieren und danach ein einziges Byte der Datei ändern, zeigen sich beide Hälften dieser Prüfung:
keytool -genkeypair -keystore key1.p12 -storetype PKCS12 -storepass changeit -alias app \
-dname "CN=Example App signing key 2026" -validity 10000 -keyalg EC -groupname secp256r1 -sigalg SHA256withECDSA
apksigner sign --ks key1.p12 --ks-pass pass:changeit --out app-key1.apk F-Droid.apk
apksigner verify -v --print-certs app-key1.apk
cp app-key1.apk tampered.apk
printf '\x00' | dd of=tampered.apk bs=1 seek=4000000 conv=notrunc status=none
apksigner verify -v tampered.apk
Verifies
Verified using v2 scheme (APK Signature Scheme v2): true
Verified using v3 scheme (APK Signature Scheme v3): true
V3.0 Signer: certificate DN: CN=Example App signing key 2026
V3.0 Signer: certificate SHA-256 digest: a93143a06f88894887d593f080c05b4ffd3aa9839c52378cee687987162d6d72
V3.0 Signer: key algorithm: EC
DOES NOT VERIFY
ERROR: APK Signature Scheme v3 signer #1: APK integrity check failed. CHUNKED_SHA256 digest mismatch. Expected: <66b1ea5c6952adc0c70f086346a76da06a5ab35dac770d104ff14d5ec09a9c97>, actual: <a5b1f3e628e868c150ade8cf1f3280f54ff4ae3771f20620cafbe97ad72ced57>
Die neu signierte Kopie besteht die Prüfung einwandfrei – mit einem anderen Zertifikat. Deshalb verrät dir der Digest des Signierers, nicht „Verifies“, ob ein APK vom richtigen Herausgeber stammt. Bei einer Installation über das originale F-Droid würde Android die Kopie als Update ablehnen, das mit einem anderen Schlüssel signiert ist. Der Digest CHUNKED_SHA256 wird über aufeinanderfolgende 1-MB-Chunks der Dateiabschnitte berechnet; dadurch können v2 und neuere Verfahren schnell und parallel prüfen.
Den Schlüssel rotieren: v3 und v3.1
Eine App kann ihren Signaturschlüssel nicht einfach durch erneutes Signieren wechseln: Das Update würde abgelehnt. v3 ergänzt einen Proof of Rotation, „eine einfach verkettete Liste, deren Knoten jeweils ein Signaturzertifikat enthalten, mit dem frühere Versionen der App signiert wurden“, wobei jedes Zertifikat das nächste signiert (v3). Ein Gerät, das den alten Schlüssel kennt, akzeptiert ein mit dem neuen Schlüssel signiertes APK, wenn die Rotationskette (Lineage) beide verbindet.
apksigner rotate --out lineage.bin --old-signer --ks key1.p12 --ks-pass pass:changeit \
--new-signer --ks key2.p12 --ks-pass pass:changeit
apksigner sign --ks key1.p12 --ks-pass pass:changeit --next-signer --ks key2.p12 --ks-pass pass:changeit \
--lineage lineage.bin --out app-rotated.apk F-Droid.apk
apksigner verify -v --print-certs app-rotated.apk
apksigner lineage --in app-rotated.apk --print-certs
Verified using v3 scheme (APK Signature Scheme v3): true
Verified using v3.1 scheme (APK Signature Scheme v3.1): true
V3.1 Signer: (minSdkVersion=33, maxSdkVersion=2147483647) certificate DN: CN=Example App signing key 2027
V3.1 Signer: (minSdkVersion=33, maxSdkVersion=2147483647) key algorithm: EC
V3.0 Signer: (minSdkVersion=24, maxSdkVersion=32) certificate DN: CN=Example App signing key 2026
V3.0 Signer: (minSdkVersion=24, maxSdkVersion=32) key algorithm: EC
Signer #1 in lineage certificate DN: CN=Example App signing key 2026
Has installed data capability: true
Has shared UID capability : true
Has permission capability : true
Has rollback capability : false
Has auth capability : true
Signer #2 in lineage certificate DN: CN=Example App signing key 2027
Has installed data capability: true
Has shared UID capability : true
Has permission capability : true
Has rollback capability : false
Has auth capability : true
Standardmäßig legt apksigner den neuen Schlüssel in einen v3.1-Block für Android 13 und neuer und behält den alten Schlüssel im v3.0-Block für Android 7 bis 12. Das ist Absicht: Laut AOSP wird „die APK-Schlüsselrotation für Android 12 (API-Level 31) und älter nicht empfohlen“, denn erst ab Android 13 erkennt checkSignatures die Rotationskette und „gibt die neueste Signatur zurück“. --rotation-min-sdk-version 28 erzwingt die Rotation ab Android 9; die Dokumentation von apksigner sieht das nur für Apps vor, die bereits auf älteren Plattformen rotiert haben (apksigner).
Die Fähigkeiten (Capabilities) legen fest, was der alte Schlüssel noch darf: Updates über Daten installieren, die mit ihm signiert sind, eine UID teilen, Signaturberechtigungen besitzen und (hier false) eine Rückkehr zu ihm per Rollback erlauben. Widerrufe sie mit apksigner lineage, wenn der alte Schlüssel kompromittiert wurde.
Post-Quanten-Signaturen: hybrides v3.2
Android 17 führt v3.2 ein, „ein hybrides Signaturverfahren, das den Übergang des Android-Ökosystems zur Post-Quanten-Kryptografie unterstützen soll“: Ein APK wird „sowohl mit einem klassischen Algorithmus wie RSA oder ECDSA als auch mit einem PQC-Algorithmus“ signiert, zunächst ML-DSA-65 oder ML-DSA-87, und zwar in einem Block mit der ID 0x70e1c89f, der „genau zwei Signierer enthalten muss“ (v3.2). Android 17 prüft beide; ältere Versionen überspringen den Block und nutzen v3.0 oder v3.1, die weiterhin vorhanden sein müssen. Die Plattform behandelt den PQC-Schlüssel als Rotation des klassischen, und die beiden Signierer müssen „identische vorausgehende Signaturhistorien“ haben.
keytool aus Java 25 erzeugt ML-DSA-Schlüssel (-keyalg ML-DSA-65), und die build-tools 37.0.0 signieren damit. Es brauchte einige Versuche: apksigner brach mit einer NullPointerException ab, bis beide hybriden Signierer eine Rotationskette hatten, und die PQC-Rotationskette musste eine Rotation vom selben vorherigen Schlüssel sein wie die klassische:
keytool -genkeypair -keystore pq.p12 -storetype PKCS12 -storepass changeit -alias app \
-dname "CN=Example App PQ signing key" -validity 10000 -keyalg ML-DSA-65
apksigner rotate --out lineage-pq.bin --old-signer --ks key1.p12 --ks-pass pass:changeit \
--new-signer --ks pq.p12 --ks-pass pass:changeit
apksigner sign --ks key1.p12 --ks-pass pass:changeit --next-signer --ks key2.p12 --ks-pass pass:changeit --lineage lineage.bin \
--next-signer --ks key2.p12 --ks-pass pass:changeit --hybrid-signer-role classical --signer-lineage lineage.bin \
--next-signer --ks pq.p12 --ks-pass pass:changeit --hybrid-signer-role pqc --signer-lineage lineage-pq.bin \
--hybrid-min-sdk-version 37 --out app-hybrid.apk F-Droid.apk
apksigner verify -v --print-certs app-hybrid.apk
Verifies
Verified using v2 scheme (APK Signature Scheme v2): true
Verified using v3 scheme (APK Signature Scheme v3): true
Verified using v3.1 scheme (APK Signature Scheme v3.1): true
Verified using v3.2 scheme (APK Signature Scheme v3.2): true
V3.2 Hybrid Classical Signer: (minSdkVersion=36 (dev release=true), maxSdkVersion=2147483647) certificate DN: CN=Example App signing key 2027
V3.2 Hybrid Classical Signer: (minSdkVersion=36 (dev release=true), maxSdkVersion=2147483647) key algorithm: EC
V3.2 Hybrid PQC Signer: (minSdkVersion=36 (dev release=true), maxSdkVersion=2147483647) certificate DN: CN=Example App PQ signing key
V3.2 Hybrid PQC Signer: (minSdkVersion=36 (dev release=true), maxSdkVersion=2147483647) key algorithm: ML-DSA
V3.1 Signer: (minSdkVersion=33, maxSdkVersion=2147483647) certificate DN: CN=Example App signing key 2027
V3.0 Signer: (minSdkVersion=24, maxSdkVersion=32) certificate DN: CN=Example App signing key 2026
Ein einziges APK trägt jetzt drei Generationen: key1 für Android 7 bis 12, key2 für Android 13 und neuer sowie key2 plus den ML-DSA-65-Schlüssel für die Plattform, die v3.2 unterstützt. Das hybride APK ist um 20.480 Byte größer als das einfach signierte. Selbst mit --hybrid-min-sdk-version 37 gab dieses apksigner den v3.2-Bereich als „36 (dev release=true)“ aus – das ist die Kodierung, die es für eine Plattform verwendet, die noch in Entwicklung ist; prüfe die Ausgabe der build-tools-Version, mit der du auslieferst. Die meisten Entwicklungsteams werden diese Befehle nie ausführen: Play erzeugt und verwaltet die hybriden Schlüssel (nächster Abschnitt).
v4 und inkrementelle Installationen
--v4-signing-enabled true schreibt eine .idsig-Datei neben das APK. Die Datei enthält einen Merkle-Baum über das APK im fs-verity-Format und eine Signatur über die Wurzel des Baums, sodass adb install --incremental die App starten kann, bevor alle Bytes angekommen sind. AOSP sagt ausdrücklich: „Eine v4-Signatur erfordert eine ergänzende v2- oder v3-Signatur.“ Im Versuch war die Signaturdatei für das 12,6-MB-APK 103.041 Byte groß, und apksigner verify --v4-signature-file app-v4.apk.idsig meldete Verified using v4 scheme (APK Signature Scheme v4): true. v4 ist eine Funktion für Entwicklung und Streaming; in Stores wird es nicht hochgeladen.
Play App Signing und Entwicklerverifizierung
Bei Google Play ist das, was auf den Geräten installiert wird, meist nicht mit deinem Schlüssel signiert. Mit Play App Signing signierst du das App Bundle mit einem Upload-Schlüssel („ein RSA-Schlüssel mit 2048 Bit oder mehr“), und Google signiert die APKs, die es ausliefert, mit dem App-Signaturschlüssel neu, den es selbst verwahrt. Das hat zwei Folgen:
- Ein verlorener oder in fremde Hände geratener Upload-Schlüssel lässt sich ersetzen: „Du wirst nicht aus deiner App ausgesperrt“; in der Play Console beantragst du mit einem neuen Zertifikat das Zurücksetzen des Upload-Schlüssels.
- Die Rotation des App-Signaturschlüssels („Schlüsselupgrade“, key upgrade) ist ein Vorgang in der Play Console. Play nimmt neue Apps inzwischen „in die Post-Quanten-taugliche, hybride Signatur mit von Google generierten Schlüsseln“ auf: „ein klassischer RSA-Schlüssel mit 4096 Bit und ein Post-Quanten-Schlüssel für ML-DSA-65“, dazu ein klassischer Schlüssel für ältere Geräte, „sodass deine App drei verschiedene Schlüssel verwendet“. Laut Play ist die hybride Signatur derzeit nicht mit v4 kompatibel; für Installationen auf Android 17 und neuer bietet Play ein jährliches Schlüsselupgrade an.
Außerhalb von Play zählt der Signaturschlüssel noch mehr. Die Entwicklerverifizierung von Android registriert Entwickler und ihre Paketnamen samt Signaturschlüsseln für Apps, die auf zertifizierten Geräten installiert werden: Die Schutzmaßnahmen gelten seit dem 30. September 2026 in Brasilien, Indonesien, Singapur und Thailand, und Google plant, die Verifizierung 2027 weltweit auszuweiten. In den FAQ heißt es unmissverständlich: „Wenn du deinen Signaturschlüssel verlierst, kannst du deine Pakete nicht registrieren.“
Häufige Fehler
- Das APK nach dem Signieren ändern. Mit
apksignergilt: „zipalignmuss vor dem Signieren der APK-Datei ausgeführt werden“ (zipalign); dasselbe gilt für jedes Tool, das das ZIP neu schreibt. Jede Änderung nach dem Signieren führt zu der oben gezeigten Abweichung des Digests. - Auf „Verifies“ vertrauen. Jeder Schlüssel erzeugt eine gültige Signatur. Vergleiche den SHA-256-Digest des Signiererzertifikats mit dem erwarteten (die Play Console zeigt deinen; F-Droid und viele Open-Source-Projekte veröffentlichen ihren).
- Mit v3 auf Android 12 und älter rotieren, ohne dass es dafür einen Grund gibt. Lass
apksignerauf v3.1 zielen. - Nur eine Kopie des Signaturschlüssels. Für Apps außerhalb von Play gibt es kein Zurücksetzen: Der Schlüssel ist die App.
- Schlüssel im Repository. Bewahre den Upload-Schlüssel in einem hardwaregestützten oder Cloud-Schlüsselspeicher auf und gib der CI eine Berechtigung zum Signieren statt der Schlüsseldatei.
- Pinning des App-Signaturzertifikats im Backend (API-Allowlists, Registrierungen von OAuth-Clients, auf das Zertifikat beschränkte Firebase- oder Maps-Schlüssel), ohne ein Schlüsselupgrade einzuplanen: Die Dokumentation von Play fordert dich auf, die neuen Fingerabdrücke bei deinen API-Anbietern zu registrieren – bei hybrider Signatur sind es zwei neue Schlüssel.
Quellen
- AOSP: Überblick über die APK-Signatur, v2, v3, v3.1, v3.2, v4
- Android Developers: apksigner, Verhaltensänderungen in Android 11, Entwicklerverifizierung und die zugehörigen FAQ
- Google Play: Play App Signing verwenden
- Tools: Android SDK build-tools 37.0.0 (
apksigner), JDK 25.0.4.1 (keytool), APK des F-Droid-Clients