Android 9 unterstützt APK Schlüsselrotation , die Apps die Möglichkeit gibt , ihre Signaturschlüssel als Teil eines APK - Update zu ändern. Damit die Rotation praktikabel ist, müssen APKs Vertrauensstufen zwischen dem neuen und dem alten Signaturschlüssel angeben. Um die Schlüsselrotation unterstützen wir die aktualisierte APK Signaturschema von v2 zu v3 die neuen und alten Schlüssel zu ermöglichen, verwendet werden. V3 fügt dem APK-Signaturblock Informationen zu den unterstützten SDK-Versionen und eine Rotationsnachweis-Struktur hinzu.
APK-Signatursperre
Um die Abwärtskompatibilität mit dem v1-APK-Format aufrechtzuerhalten, werden v2- und v3-APK-Signaturen in einem APK-Signaturblock gespeichert, der sich unmittelbar vor dem zentralen ZIP-Verzeichnis befindet.
Die APK v3 Signing - Block - Format ist das gleiche wie v2 . Die v3-Signatur des APK wird als ID-Wert-Paar mit der ID 0xf05368c0 gespeichert.
APK-Signaturschema v3 Block
Das v3 - Schema wird entwickelt , um das sehr ähnlich seinem v2 Schema . Es hat das gleiche allgemeine Format und unterstützt die gleiche Signaturalgorithmus IDs , Schlüsselgrößen und EC - Kurven.
Das v3-Schema fügt jedoch Informationen zu den unterstützten SDK-Versionen und der Rotationsnachweisstruktur hinzu.
Format
APK Signature Scheme v3 - Block ist in der APK Signing - Block unter ID gespeichert 0xf05368c0
.
Das Format des APK-Signaturschema-v3-Blocks entspricht dem von v2:
- Länge-Präfix-Sequenz der Länge Präfix
signer
:- Länge-Präfix
signed data
:- Länge-Präfix-Sequenz der Länge voran
digests
:-
signature algorithm ID
-signature algorithm ID
(4 Byte) -
digest
(Länge vorangestellt)
-
- Länge-Präfix - Sequenz von X.509 -
certificates
:- Länge-Präfix X.509 -
certificate
(ASN.1 DER Form)
- Länge-Präfix X.509 -
-
minSDK
(uint32) - dieser Unterzeichner sollte ignoriert werden , wenn Plattform - Version unter dieser Nummer. -
maxSDK
(uint32) - dieser Unterzeichner sollte ignoriert werden , wenn Plattform - Version über dieser Zahl ist. - Länge-Präfix-Sequenz der Länge Präfix
additional attributes
:-
ID
(Uint32) -
value
(variable-length: Länge des zusätzlichen Attributs - 4 Bytes) -
ID - 0x3ba06f8c
-
value -
Proof-of-Rotation struct
-
- Länge-Präfix-Sequenz der Länge voran
-
minSDK
(uint32) - Duplikat minSDK Wert in Datenbereich unterzeichnet - verwendet Überprüfung dieser Signatur zu überspringen , wenn die aktuelle Plattform nicht in Reichweite ist. Muss mit dem vorzeichenbehafteten Datenwert übereinstimmen. -
maxSDK
(uint32) - Duplikat des maxSDK Wertes im Datenteil unterzeichnet - verwendet Überprüfung dieser Signatur zu überspringen , wenn die aktuelle Plattform nicht in Reichweite ist. Muss mit dem vorzeichenbehafteten Datenwert übereinstimmen. - Länge-Präfix-Sequenz der Länge voran
signatures
:-
signature algorithm ID
-signature algorithm ID
(Uint32) - Länge-Präfix
signature
übersigned data
-
- Länge-Präfix
public key
(SubjectPublicKeyInfo, ASN.1 DER Form)
- Länge-Präfix
Rotationsnachweis und selbstvertrauenswürdige alte Zertifikatsstrukturen
Die Proof-of-Rotation-Struktur ermöglicht es Apps, ihr Signaturzertifikat zu rotieren, ohne auf anderen Apps, mit denen sie kommunizieren, blockiert zu werden. Um dies zu erreichen, enthalten App-Signaturen zwei neue Daten:
- Behauptung für Dritte, dass dem Signaturzertifikat der App überall dort vertraut werden kann, wo seinen Vorgängern vertraut wird
- ältere Signaturzertifikate der App, denen die App selbst noch vertraut
Das Attribut für den Rotationsnachweis im Abschnitt für signierte Daten besteht aus einer einzeln verknüpften Liste, wobei jeder Knoten ein Signaturzertifikat enthält, das zum Signieren früherer Versionen der App verwendet wird. Dieses Attribut soll den konzeptionellen Rotationsnachweis und die selbstvertrauenswürdigen alten Zertifikate-Datenstrukturen enthalten. Die Liste ist nach Version geordnet, wobei das älteste Signaturzertifikat dem Root-Knoten entspricht. Die Datenstruktur für den Rotationsnachweis wird aufgebaut, indem das Zertifikat in jedem Knoten den nächsten in der Liste signiert und somit jeden neuen Schlüssel mit einem Beweis versehen wird, dass er genauso vertrauenswürdig sein sollte wie der/die ältere(n) Schlüssel.
Die Self-Trusted-Old-Certs-Datenstruktur wird aufgebaut, indem jedem Knoten Flags hinzugefügt werden, die seine Mitgliedschaft und Eigenschaften im Satz angeben. Beispielsweise kann ein Flag vorhanden sein, das anzeigt, dass dem Signaturzertifikat an einem bestimmten Knoten vertraut wird, um Android-Signaturberechtigungen zu erhalten. Dieses Flag ermöglicht es anderen Apps, die mit dem älteren Zertifikat signiert sind, weiterhin eine Signaturberechtigung zu erhalten, die von einer App definiert wird, die mit dem neuen Signaturzertifikat signiert ist. Weil die ganze proof-of-Dreh Attribut besteht in dem signierten Datenabschnitt des v3 signer
Feld wird durch den Schlüssel verwendet , die geschützt enthält apk zu unterzeichnen.
Dieses Format schließt aus mehreren Signaturschlüssel und die Konvergenz der verschiedenen Vorfahr Signaturzertifikate zu einem (mehreren Startknoten zu einem gemeinsamen Enke).
Format
Die Proof-of-Rotation innerhalb der APK Signatur gespeichert Schema v3 - Block unter ID 0x3ba06f8c
. Sein Format ist:
- Länge-Präfix-Sequenz der Länge vorangestellt
levels
:- Länge-Präfix
signed data
(durch die vorherigen cert - falls vorhanden)- Länge-Präfix X.509 -
certificate
(ASN.1 DER Form) -
signature algorithm ID
-signature algorithm ID
(Uint32) - Algorithmus , der von cert in vorheriger Ebene verwendet
- Länge-Präfix X.509 -
-
flags
(uint32) - Flags , die anzeigen , ob dieses Zertifikat in der Selbst trusted-old-Zert struct sein sollte, und für die Operationen. -
signature algorithm ID
(uint32) - müssen in der nächsten Ebene , das eine vom signierten Datenabschnitt entsprechen. - Länge-Präfix
signature
über die obensigned data
- Länge-Präfix
Mehrere Zertifikate
Android behandelt derzeit ein APK, das mit mehreren Zertifikaten signiert ist, als habe es eine eindeutige Signaturidentität, die von den Zertifikaten getrennt ist. Somit bildet das Rotationsnachweisattribut im signierten Datenabschnitt einen gerichteten azyklischen Graphen, der besser als eine einzeln verknüpfte Liste betrachtet werden könnte, wobei jeder Satz von Unterzeichnern für eine gegebene Version einen Knoten darstellt. Dies erhöht die Komplexität der Rotationsnachweisstruktur (Multi-Signer-Version unten). Insbesondere die Bestellung wird zum Problem. Darüber hinaus ist es nicht mehr möglich, APKs unabhängig voneinander zu signieren, da in der Proof-of-Rotation-Struktur die alten Signaturzertifikate die neuen Zertifikate signieren müssen, anstatt sie einzeln zu signieren. Zum Beispiel könnte ein APK, das mit Schlüssel A signiert ist, das mit zwei neuen Schlüsseln B und C signiert werden möchte, vom B-Unterzeichner nicht einfach eine Signatur von A oder B enthalten, da dies eine andere Signaturidentität als B und C ist bedeutet, dass sich die Unterzeichner vor dem Aufbau einer solchen Struktur abstimmen müssen.
Rotationsnachweisattribut für mehrere Unterzeichner
- Länge-Präfix-Sequenz der Länge voran
sets
:-
signed data
(durch die vorherigen Satz - falls vorhanden)- Länge-Präfix - Sequenz von
certificates
- Länge-Präfix X.509 -
certificate
(ASN.1 DER Form)
- Länge-Präfix X.509 -
- Sequenz von
signature algorithm IDs
(Uint32) - ein für jedes Zertifikat aus dem vorhergehenden Satz, in der gleichen Reihenfolge.
- Länge-Präfix - Sequenz von
-
flags
(uint32) - Flags , die anzeigen , ob dieser Satz von certs in der Selbst trusted-old-Zert struct sein sollte, und für die Operationen. - Länge-Präfix-Sequenz der Länge voran
signatures
:-
signature algorithm ID
(uint32) - muss mit dem von dem signierten Daten übereinstimmen Abschnitt - Länge-Präfix
signature
über die obensigned data
-
-
Mehrere Vorfahren in einer Rotationsnachweisstruktur
Das v3-Schema verarbeitet auch nicht zwei verschiedene Schlüssel, die zu demselben Signaturschlüssel für dieselbe App rotieren. Dies unterscheidet sich vom Fall einer Akquisition, bei der das übernehmende Unternehmen die erworbene App verschieben möchte, um ihren Signaturschlüssel zum Teilen von Berechtigungen zu verwenden. Die Übernahme wird als unterstützter Anwendungsfall angesehen, da sich die neue App durch ihren Paketnamen unterscheiden würde und ihre eigene Rotationsnachweisstruktur enthalten könnte. Der nicht unterstützte Fall, dass dieselbe App zwei verschiedene Pfade hat, um zum selben Zertifikat zu gelangen, bricht viele der Annahmen, die im Schlüsselrotationsdesign getroffen wurden.
Überprüfung
In Android 9 und höher können APKs gemäß dem APK-Signaturschema v3, v2-Schema oder v1-Schema verifiziert werden. Ältere Plattformen ignorieren v3-Signaturen und versuchen, v2-Signaturen zu überprüfen, dann v1.
Abbildung 1. APK Signaturprüfungsprozess
Überprüfung des APK-Signaturschemas v3
- Suchen Sie den APK-Signaturblock und überprüfen Sie Folgendes:
- Zwei Größenfelder des APK-Signaturblocks enthalten denselben Wert.
- Dem ZIP-Zentralverzeichnis folgt unmittelbar der Eintrag ZIP-Ende des Zentralverzeichnisses.
- ZIP Auf das Ende des zentralen Verzeichnisses folgen keine weiteren Daten.
- Suchen Sie den ersten APK-Signaturschema v3-Block im APK-Signaturblock. Wenn die v3 - Block vorhanden ist, 3. Andernfalls zu Schritt fort, fällt zurück , um die APK zu überprüfen , v2 - Schema verwendet .
- Für jeden
signer
in der APK Signature Scheme v3 - Block mit einem Min- und Max - SDK - Version , die in Reichweite der aktuellen Plattform ist:- Wählen Sie die stärksten unterstützte
signature algorithm ID
vonsignatures
. Die Reihenfolge der Stärke hängt von jeder Implementierungs-/Plattformversion ab. - Überprüfen Sie die entsprechende
signature
vonsignatures
gegensigned data
mitpublic key
. (Es ist jetzt sicher zu analysierensigned data
.) - Überprüfen Sie die Min- und Max - SDK - Versionen in den signierten Daten entsprechen denen für den angegebenen
signer
. - Stellen Sie sicher , dass die geordnete Liste von Signaturalgorithmus IDs in
digests
undsignatures
identisch ist. (Dies soll das Ablösen/Hinzufügen der Unterschrift verhindern.) - Berechne Digest of APK Inhalt unter Verwendung der gleichen Digest - Algorithmus , wie der Algorithmus , der von dem Signaturalgorithmus verwendet verdauen.
- Überprüfen, ob der berechnete Digest zu dem entsprechenden identischen
digest
vondigests
. - Stellen Sie sicher , dass SubjectPublicKeyInfo des ersten
certificate
voncertificates
identisch ist mitpublic key
. - Wenn das Proof-of-Rotation - Attribut für das existiert
signer
überprüfen, ob die Struktur gültig ist , und diesesigner
sind das letzte Zertifikat in der Liste.
- Wählen Sie die stärksten unterstützte
- Überprüfung erfolgreich , wenn genau ein
signer
in einem Bereich von der aktuellen Plattform und Schritt 3 für das gelingt gefunden wurdesigner
.
Validierung
Um Test , dass Ihr Gerät unterstützt richtig v3, führen Sie die PkgInstallSignatureVerificationTest.java
CTS - Tests in cts/hostsidetests/appsecurity/src/android/appsecurity/cts/
.