APK-Signaturschema v3

Android 9 unterstützt die APK-Schlüsselrotation, mit der Apps ihren Signaturschlüssel im Rahmen eines APK-Updates ändern können. Damit die Rotation praktisch ist, müssen APKs das Vertrauensniveau zwischen dem neuen und dem alten Signaturschlüssel angeben. Zur Unterstützung der Schlüsselrotation haben wir das APK-Signaturschema von Version 2 auf Version 3 aktualisiert, damit sowohl der neue als auch der alte Schlüssel verwendet werden können. In Version 3 werden dem APK-Signaturblock Informationen zu den unterstützten SDK-Versionen und eine Proof-of-Rotation-Struktur hinzugefügt.

Blockierung der APK-Signatur

Zur Abwärtskompatibilität mit dem APK-Format v1 werden APK-Signaturen der Version 2 und 3 in einem APK-Signaturblock gespeichert, der sich direkt vor dem ZIP-Zentralverzeichnis befindet.

Das Blockformat für die APK-Signatur von Version 3 entspricht dem von Version 2. Die V3-Signatur des APK wird als ID-Wert-Paar mit der ID 0xf05368c0 gespeichert.

Blockieren des APK-Signaturschemas v3

Das V3-Schema ist dem V2-Schema sehr ähnlich. Es hat dasselbe allgemeine Format und unterstützt dieselben IDs für Signaturalgorithmen, Schlüsselgrößen und EC-Kurven.

Das V3-Schema enthält jedoch Informationen zu den unterstützten SDK-Versionen und zum Proof-of-Rotation-Attribut.

Formatieren

Der Block „APK Signature Scheme v3“ wird im Block „APK Signing“ unter der ID 0xf05368c0 gespeichert.

Das Format des Blocks für das APK-Signaturschema 3 entspricht dem von Version 2:

  • Sequenz mit Längenpräfix von signer mit Längenpräfix:
    • Längenpräfix signed data:
      • Sequenz mit Längenpräfix von digests mit Längenpräfix:
        • signature algorithm ID (4 Byte)
        • digest (mit Längenpräfix)
      • Eine mit einer Längenpräfixe versehene Sequenz von X.509-certificates:
        • X.509 certificate mit Längenpräfix (ASN.1 DER-Format)
      • minSDK (uint32): Dieser Unterzeichner sollte ignoriert werden, wenn die Plattformversion unter dieser Zahl liegt.
      • maxSDK (uint32): Dieser Unterzeichner sollte ignoriert werden, wenn die Plattformversion über dieser Zahl liegt.
      • Sequenz mit Längenpräfix von additional attributes mit Längenpräfix:
        • ID (uint32)
        • value (variable Länge: Länge des zusätzlichen Attributs – 4 Byte)
        • ID - 0x3ba06f8c
        • value - Proof-of-Rotation-Struktur
    • minSDK (uint32): Duplikat des minSDK-Werts im Abschnitt „signed data“ (signierte Daten). Wird verwendet, um die Überprüfung dieser Signatur zu überspringen, wenn sich die aktuelle Plattform nicht im Bereich befindet. Muss mit dem signierten Datenwert übereinstimmen.
    • maxSDK (uint32): Duplikat des maxSDK-Werts im Abschnitt mit den signierten Daten. Wird verwendet, um die Überprüfung dieser Signatur zu überspringen, wenn die aktuelle Plattform nicht im Bereich liegt. Muss mit dem signierten Datenwert übereinstimmen.
    • Sequenz mit Längenpräfix von signatures mit Längenpräfix:
      • signature algorithm ID (uint32)
      • Längenpräfix signature über signed data
    • Längenvorangestellte public key (SubjectPublicKeyInfo, ASN.1 DER-Format)

Strukturen für Rotationsnachweis und selbst vertrauenswürdige alte Zertifikate

Mit dem Proof-of-Rotation-Attribut können Apps ihr Signaturzertifikat wechseln, ohne von anderen Apps, mit denen sie kommunizieren, blockiert zu werden. Dazu enthalten App-Signaturen zwei neue Daten:

  • Behauptung für Dritte, dass das Signaturzertifikat der App vertrauenswürdig ist, wenn seine Vorgänger vertrauenswürdig sind
  • ältere Signaturzertifikate der App, denen die App selbst noch vertraut

Das Attribut „Proof-of-Rotation“ im Abschnitt „Signed Data“ besteht aus einer einzelnen verketteten Liste, wobei jeder Knoten ein Signaturzertifikat enthält, das zum Signieren vorheriger Versionen der App verwendet wurde. Dieses Attribut soll die Datenstrukturen „Proof-of-Rotation“ und „Self-Trusted-Old-Certs“ enthalten. Die Liste ist nach Version sortiert. Das älteste Signaturzertifikat entspricht dem Stammknoten. Die Datenstruktur für den Proof-of-Rotation wird erstellt, indem das Zertifikat in jedem Knoten das nächste in der Liste signiert. Dadurch wird jedem neuen Schlüssel ein Nachweis hinzugefügt, dass er genauso vertrauenswürdig sein sollte wie die älteren Schlüssel.

Die Datenstruktur „self-trusted-old-certs“ wird erstellt, indem jedem Knoten Flags hinzugefügt werden, die seine Zugehörigkeit und Eigenschaften im Satz angeben. Beispielsweise kann ein Flag vorhanden sein, das angibt, dass das Signaturzertifikat an einem bestimmten Knoten für die Erlangung von Android-Signaturberechtigungen vertrauenswürdig ist. Mit diesem Flag kann anderen Apps, die mit dem älteren Zertifikat signiert wurden, weiterhin eine Signaturberechtigung gewährt werden, die von einer App definiert wurde, die mit dem neuen Signaturzertifikat signiert wurde. Da sich das gesamte Attribut „proof-of-rotation“ im Abschnitt mit den signierten Daten des v3-signer-Felds befindet, wird es durch den Schlüssel geschützt, mit dem die enthaltene APK signiert wurde.

Dieses Format schließt mehrere Signaturschlüssel und die Zusammenführung von verschiedenen übergeordneten Signaturzertifikaten zu einem einzigen aus (mehrere Startknoten zu einem gemeinsamen Ziel).

Formatieren

Der Nachweis der Rotation wird im Block „APK Signature Scheme v3“ unter der ID 0x3ba06f8c gespeichert. Das Format ist:

  • Sequenz mit Längenpräfix von levels mit Längenpräfix:
    • Längenpräfix signed data (vom vorherigen Zertifikat, falls vorhanden)
      • X.509 certificate mit Längenpräfix (ASN.1 DER-Format)
      • signature algorithm ID (uint32): Algorithmus, der vom Zertifikat in der vorherigen Ebene verwendet wird
    • flags (uint32): Flags, die angeben, ob dieses Zertifikat im „self-trusted-old-certs“-String enthalten sein soll und für welche Vorgänge.
    • signature algorithm ID (uint32): Muss mit dem Wert im Abschnitt mit signierten Daten der nächsten Ebene übereinstimmen.
    • Längenpräfix signature über dem obigen signed data

Mehrere Zertifikate

Mehrere Unterzeichner werden nicht unterstützt und Google Play veröffentlicht keine Apps, die mit mehreren Zertifikaten signiert sind.

Bestätigung

Unter Android 9 und höher können APKs gemäß dem APK-Signaturschema Version 3, Version 2 oder Version 1 überprüft werden. Ältere Plattformen ignorieren V3-Signaturen und versuchen, V2-Signaturen und dann V1-Signaturen zu überprüfen.

Überprüfung der APK-Signatur

Abbildung 1: Überprüfung der APK-Signatur

Überprüfung des APK-Signaturschemas v3

  1. Suchen Sie den Block für die APK-Signatur und prüfen Sie Folgendes:
    1. Zwei Feldgrößen des APK-Signaturblocks enthalten denselben Wert.
    2. Auf das ZIP-Zentralverzeichnis folgt unmittelbar der ZIP-Eintrags-Schlüssel „End of Central Directory“.
    3. Dem ZIP-End of Central Directory folgen keine weiteren Daten.
  2. Suchen Sie im APK-Signaturblock nach dem ersten Block des APK-Signaturschemas v3. Wenn der v3-Block vorhanden ist, fahren Sie mit Schritt 3 fort. Andernfalls können Sie das APK mit dem V2-Schema überprüfen.
  3. Für jede signer im APK-Signaturschema-V3-Block mit einer min und max SDK-Version, die im Bereich der aktuellen Plattform liegt:
    1. Wählen Sie die stärkste unterstützte signature algorithm ID aus signatures aus. Die Reihenfolge der Stärke ist von der jeweiligen Implementierung/Plattformversion abhängig.
    2. Prüfen Sie mit public key, ob der entsprechende signature aus signatures mit signed data übereinstimmt. (signed data kann jetzt sicher geparst werden.)
    3. Prüfen Sie, ob die Mindest- und Höchst-SDK-Versionen in den signierten Daten mit den für die signer angegebenen Versionen übereinstimmen.
    4. Prüfen Sie, ob die sortierte Liste der Signaturalgorithmus-IDs in digests und signatures identisch ist. (Damit wird verhindert, dass Signaturen entfernt oder hinzugefügt werden.)
    5. Berechnen Sie den Digest des APK-Inhalts mit demselben Digest-Algorithmus wie der vom Signaturalgorithmus verwendete Digest-Algorithmus.
    6. Prüfen Sie, ob der berechnete Digest mit dem entsprechenden digest aus digests identisch ist.
    7. Prüfen Sie, ob das SubjectPublicKeyInfo der ersten certificate von certificates mit public key identisch ist.
    8. Wenn das Attribut „proof-of-rotation“ für signer vorhanden ist, prüfen Sie, ob das signer-Objekt gültig ist und ob es sich bei diesem signer um das letzte Zertifikat in der Liste handelt.
  4. Die Überprüfung ist erfolgreich, wenn genau eine signer im Bereich der aktuellen Plattform gefunden wurde und Schritt 3 für diese signer erfolgreich war.

Zertifizierungsstufe

Führen Sie die PkgInstallSignatureVerificationTest.java CTS-Tests in cts/hostsidetests/appsecurity/src/android/appsecurity/cts/ aus, um zu prüfen, ob Ihr Gerät v3 ordnungsgemäß unterstützt.