Android 9 unterstützt die APK-Schlüsselrotation , was Apps die Möglichkeit gibt, ihren Signaturschlüssel im Rahmen eines APK-Updates zu ändern. Um die Rotation praktikabel zu machen, müssen APKs Vertrauensstufen zwischen dem neuen und dem alten Signaturschlüssel angeben. Um die Schlüsselrotation zu unterstützen, haben wir das APK-Signaturschema von Version 2 auf Version 3 aktualisiert, um die Verwendung der neuen und alten Schlüssel zu ermöglichen. V3 fügt dem APK-Signaturblock Informationen zu den unterstützten SDK-Versionen und eine Proof-of-Rotation-Struktur hinzu.
APK-Signaturblock
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 ZIP-Zentralverzeichnis befindet.
Das APK-Signaturblockformat der Version 3 ist dasselbe wie das Format der Version 2 . Die v3-Signatur des APK wird als ID-Wert-Paar mit der ID 0xf05368c0 gespeichert.
APK Signature Scheme v3 Block
Das v3-Schema ist so konzipiert, dass es dem v2-Schema sehr ähnlich ist. Es hat das gleiche allgemeine Format und unterstützt die gleichen Signaturalgorithmus-IDs , Schlüsselgrößen und EC-Kurven.
Das v3-Schema fügt jedoch Informationen zu den unterstützten SDK-Versionen und der Proof-of-Rotation-Struktur hinzu.
Format
Der APK Signature Scheme v3 Block wird im APK Signing Block unter der ID 0xf05368c0
gespeichert.
Das Format des APK Signature Scheme v3 Blocks folgt dem von v2:
- Längenpräfixierte Sequenz des längenpräfixierten
signer
:-
signed data
mit Längenpräfix:- Längenpräfixierte Folge von
digests
mit Längenpräfix:-
signature algorithm ID
(4 Bytes) -
digest
(mit Längenpräfix)
-
- Längenpräfixierte Sequenz von X.509-
certificates
:- X.509-
certificate
mit Längenpräfix (ASN.1 DER-Form)
- X.509-
-
minSDK
(uint32) – dieser Unterzeichner sollte ignoriert werden, wenn die Plattformversion unter dieser Nummer liegt. -
maxSDK
(uint32) – dieser Unterzeichner sollte ignoriert werden, wenn die Plattformversion über dieser Nummer liegt. - Längenpräfixierte Folge von längenpräfixierten
additional attributes
:-
ID
(uint32) -
value
(Variablenlänge: Länge des zusätzlichen Attributs - 4 Bytes) -
ID - 0x3ba06f8c
-
value -
Proof-of-Rotation-Struktur
-
- Längenpräfixierte Folge von
-
minSDK
(uint32) – Duplikat des minSDK-Werts im signierten Datenabschnitt – wird verwendet, um die Überprüfung dieser Signatur zu überspringen, wenn die aktuelle Plattform nicht im Bereich liegt. Muss mit dem vorzeichenbehafteten Datenwert übereinstimmen. -
maxSDK
(uint32) – Duplikat des maxSDK-Werts im signierten Datenabschnitt – wird verwendet, um die Überprüfung dieser Signatur zu überspringen, wenn die aktuelle Plattform nicht im Bereich liegt. Muss mit dem vorzeichenbehafteten Datenwert übereinstimmen. - Längenpräfixierte Folge von längenpräfixierten
signatures
:-
signature algorithm ID
(uint32) -
signature
mit Längenpräfix übersigned data
-
-
public key
mit Längenpräfix (SubjectPublicKeyInfo, ASN.1 DER-Form)
-
Proof-of-Rotation und Self-Trusted-Old-Certs-Strukturen
Die Proof-of-Rotation-Struktur ermöglicht es Apps, ihr Signaturzertifikat zu rotieren, ohne für andere Apps, mit denen sie kommunizieren, blockiert zu werden. Um dies zu erreichen, enthalten App-Signaturen zwei neue Daten:
- Zusicherung für Dritte, dass dem Signaturzertifikat der App überall dort vertraut werden kann, wo seinen Vorgängern vertraut wird
- Die älteren Signaturzertifikate der App, denen die App selbst noch vertraut
Das Proof-of-Rotation-Attribut im Abschnitt „Signierte Daten“ besteht aus einer einfach verknüpften Liste, wobei jeder Knoten ein Signaturzertifikat enthält, das zum Signieren früherer Versionen der App verwendet wurde. Dieses Attribut soll die konzeptionellen Proof-of-Rotation- und Self-Trusted-Old-Certs-Datenstrukturen enthalten. Die Liste ist nach Version sortiert, wobei das älteste Signaturzertifikat dem Stammknoten entspricht. Die Proof-of-Rotation-Datenstruktur wird dadurch aufgebaut, dass das Zertifikat in jedem Knoten das nächste in der Liste signiert und so jedem neuen Schlüssel den Beweis verleiht, dass er genauso vertrauenswürdig sein sollte wie der/die ältere(n) Schlüssel.
Die Datenstruktur „Self-Trusted-Old-Certs“ wird durch das Hinzufügen von Flags zu jedem Knoten erstellt, die seine Mitgliedschaft und Eigenschaften im Satz angeben. Beispielsweise kann ein Flag vorhanden sein, das angibt, dass das Signaturzertifikat an einem bestimmten Knoten für den Erhalt von Android-Signaturberechtigungen vertrauenswürdig ist. Dieses Flag ermöglicht es anderen Apps, die mit dem älteren Zertifikat signiert wurden, weiterhin eine Signaturberechtigung zu erhalten, die von einer App definiert wurde, die mit dem neuen Signaturzertifikat signiert wurde. Da sich das gesamte Proof-of-Rotation-Attribut im signierten Datenabschnitt des v3- signer
befindet, ist es durch den Schlüssel geschützt, der zum Signieren der enthaltenden APK verwendet wird.
Dieses Format schließt mehrere Signaturschlüssel und die Konvergenz verschiedener Vorfahren-Signaturzertifikate zu einem aus (mehrere Startknoten zu einer gemeinsamen Senke).
Format
Der Rotationsnachweis wird im APK Signature Scheme v3 Block unter der ID 0x3ba06f8c
gespeichert. Sein Format ist:
- längenpräfixierte Folge von längenpräfixierten
levels
:-
signed data
mit Längenpräfix (vom vorherigen Zertifikat – falls vorhanden)- X.509-
certificate
mit Längenpräfix (ASN.1 DER-Form) -
signature algorithm ID
(uint32) – Algorithmus, der von cert in der vorherigen Ebene verwendet wurde
- X.509-
-
flags
(uint32) – Flags, die angeben, ob dieses Zertifikat in der Struktur „self-trusted-old-certs“ enthalten sein soll und für welche Vorgänge. -
signature algorithm ID
(uint32) – muss mit der aus dem signierten Datenabschnitt in der nächsten Ebene übereinstimmen. - längenpräfixierte
signature
über den obensigned data
-
Mehrere Zertifikate
Android behandelt derzeit ein APK, das mit mehreren Zertifikaten signiert ist, so, als hätte es eine eindeutige Signaturidentität, die von den Zertifikaten, aus denen es besteht, getrennt ist. Somit bildet das Proof-of-Rotation-Attribut im Abschnitt mit vorzeichenbehafteten Daten einen gerichteten azyklischen Graphen, der besser als einfach verknüpfte Liste betrachtet werden könnte, wobei jeder Satz von Unterzeichnern für eine bestimmte Version einen Knoten darstellt. Dies erhöht die Komplexität der Proof-of-Rotation-Struktur (Version mit mehreren Unterzeichnern 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 den neuen Satz von Zertifikaten signieren müssen, anstatt sie einzeln zu signieren. Beispielsweise könnte ein mit Schlüssel A signiertes APK, das mit zwei neuen Schlüsseln B und C signiert werden möchte, nicht dafür sorgen, dass der B-Unterzeichner einfach eine Signatur von A oder B einfügt, da dies eine andere Signaturidentität als B und C ist. Dies wäre der Fall bedeuten, dass sich die Unterzeichner vor dem Aufbau einer solchen Struktur abstimmen müssen.
Rotationsnachweisattribut für mehrere Unterzeichner
- längenpräfixierte Folge von längenpräfixierten
sets
:-
signed data
(nach vorherigem Satz – falls vorhanden)- längenpräfixierte Folge von
certificates
- X.509-
certificate
mit Längenpräfix (ASN.1 DER-Form)
- X.509-
- Reihenfolge der
signature algorithm IDs
(uint32) – eine für jedes Zertifikat aus dem vorherigen Satz, in derselben Reihenfolge.
- längenpräfixierte Folge von
-
flags
(uint32) – Flags, die angeben, ob dieser Satz von Zertifikaten in der Struktur „self-trusted-old-certs“ enthalten sein soll und für welche Vorgänge. - Längenpräfixierte Folge von längenpräfixierten
signatures
:-
signature algorithm ID
(uint32) – muss mit der aus dem signierten Datenabschnitt übereinstimmen - längenpräfixierte
signature
über den obensigned data
-
-
Mehrere Vorfahren in der Proof-of-Rotation-Struktur
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 erwerbende Unternehmen die erworbene App so verschieben möchte, dass sie ihren Signaturschlüssel zum Teilen von Berechtigungen verwendet. Die Übernahme wird als unterstützter Anwendungsfall angesehen, da sich die neue App durch ihren Paketnamen unterscheiden würde und eine eigene Proof-of-Rotation-Struktur enthalten könnte. Der nicht unterstützte Fall, dass dieselbe App zwei unterschiedliche Pfade hat, um zum selben Zertifikat zu gelangen, verstößt gegen viele der im Schlüsselrotationsdesign getroffenen Annahmen.
Überprüfung
In Android 9 und höher können APKs gemäß dem APK-Signaturschema v3, v2-Schema oder v1-Schema überprüft werden. Ältere Plattformen ignorieren v3-Signaturen und versuchen, v2-Signaturen und dann v1 zu überprüfen.
Überprüfung des APK Signature Scheme v3
- Suchen Sie den APK-Signaturblock und überprüfen Sie Folgendes:
- Zwei Größenfelder des APK-Signaturblocks enthalten denselben Wert.
- Auf „ZIP Central Directory“ folgt unmittelbar der Eintrag „ZIP End of Central Directory“.
- Auf das ZIP-Ende des zentralen Verzeichnisses folgen keine weiteren Daten.
- Suchen Sie den ersten APK Signature Scheme v3-Block im APK-Signaturblock. Wenn der v3-Block vorhanden ist, fahren Sie mit Schritt 3 fort. Andernfalls greifen Sie auf die Überprüfung des APK mithilfe des v2-Schemas zurück.
- Für jeden
signer
im APK Signature Scheme v3-Block mit einer minimalen und maximalen SDK-Version, die im Bereich der aktuellen Plattform liegt:- Wählen Sie aus
signatures
die stärkste unterstütztesignature algorithm ID
aus. Die Reihenfolge der Stärke hängt von der jeweiligen Implementierung/Plattformversion ab. - Überprüfen Sie die entsprechende
signature
vonsignatures
anhandsigned data
mithilfepublic key
. (Es ist jetzt sicher,signed data
zu analysieren.) - Stellen Sie sicher, dass die minimalen und maximalen SDK-Versionen in den signierten Daten mit denen übereinstimmen, die für den
signer
angegeben wurden. - Stellen Sie sicher, dass die geordnete Liste der Signaturalgorithmus-IDs in
digests
undsignatures
identisch ist. (Dies dient dazu, das Entfernen/Hinzufügen von Signaturen zu verhindern.) - Berechnen Sie den Digest von APK-Inhalten mit demselben Digest-Algorithmus wie dem Digest-Algorithmus, der vom Signaturalgorithmus verwendet wird.
- Stellen Sie sicher, dass der berechnete Digest mit dem entsprechenden
digest
ausdigests
identisch ist. - Stellen Sie sicher
certificates
dass SubjectPublicKeyInfo des erstencertificate
mitpublic key
identisch ist. - Wenn das Proof-of-Rotation-Attribut für den
signer
vorhanden ist, überprüfen Sie, ob die Struktur gültig ist und diesersigner
das letzte Zertifikat in der Liste ist.
- Wählen Sie aus
- Die Überprüfung ist erfolgreich, wenn genau ein
signer
im Bereich der aktuellen Plattform gefunden wurde und Schritt 3 für diesensigner
erfolgreich war.
Validierung
Um zu testen, ob Ihr Gerät v3 ordnungsgemäß unterstützt, führen Sie die CTS-Tests PkgInstallSignatureVerificationTest.java
in cts/hostsidetests/appsecurity/src/android/appsecurity/cts/
aus.