APK-Signaturschema v4

Android 11 unterstützt ein Streaming-kompatibles Signaturschema mit dem APK Signaturschema v4. Die v4-Signatur basiert auf dem Merkle-Hashbaum der über alle Bytes des APK berechnet wird. Sie folgt der Struktur des Hash-Baums fs-verity exakt (z. B. ohne Auffüllung). Salt und null Padding für den letzten Block). Android 11 speichert die Signatur in einer separaten Datei, <apk name>.apk.idsigeine v4-Signatur erfordert eine ergänzende v2- oder v3-Signatur.

Dateiformat

Alle numerischen Felder sind in Little-Endian geschrieben. Alle Felder enthalten genau die Nummer von Byte als ihr sizeof()-Wert, kein implizites Padding oder Ausrichtung hinzugefügt.

Nachfolgend finden Sie eine Hilfsstruktur zur Vereinfachung der Definitionen.

template <class SizeT>
struct sized_bytes {
        SizeT size;
        byte bytes[size];
};

Inhalt der Hauptdatei:

struct V4Signature {
        int32 version; // only version 2 is supported as of now
        sized_bytes<int32> hashing_info;
        sized_bytes<int32> signing_info;
        sized_bytes<int32> merkle_tree;  // optional
};
<ph type="x-smartling-placeholder">

hashing_info sind die für den Hash-Baum verwendeten Parameter Generation + dem Root-Hash:

struct hashing_info.bytes {
    int32 hash_algorithm;    // only 1 == SHA256 supported
    int8 log2_blocksize;     // only 12 (block size 4096) supported now
    sized_bytes<int32> salt; // used exactly as in fs-verity, 32 bytes max
    sized_bytes<int32> raw_root_hash; // salted digest of the first Merkle tree page
};

signing_info ist die folgende Struktur:

struct signing_info.bytes {
    sized_bytes<int32> apk_digest;  // used to match with the corresponding APK
    sized_bytes<int32> x509_certificate; // ASN.1 DER form
    sized_bytes<int32> additional_data; // a free-form binary data blob
    sized_bytes<int32> public_key; // ASN.1 DER, must match the x509_certificate
    int32 signature_algorithm_id; // see the APK v2 doc for the list
    sized_bytes<int32> signature;
};
<ph type="x-smartling-placeholder">
  • apk_digest stammt aus dem v3-Signaturblock des APK oder, falls nicht, vorhanden, aus dem V2-Block (siehe apk_digest)

Zum Erstellen und Prüfen muss ein signature-Code serialisiert werden folgenden Daten in binären Blob und übergeben sie an die Signatur-/Verifizierungsalgorithmus als signierte Daten verwenden:

struct V4DataForSigning {
        int32 size;
        int64 file_size; // the size of the file that's been hashed.
        hashing_info.hash_algorithm;
        hashing_info.log2_blocksize;
        hashing_info.salt;
        hashing_info.raw_root_hash;
        signing_info.apk_digest;
        signing_info.x509_certificate;
        signing_info.additional_data;
};
  1. merkle_tree ist der ganze Merkle-Baum des APK, der wie in der Dokumentation zu fs-verity beschrieben berechnet wird.
<ph type="x-smartling-placeholder">

Produzenten und Verbraucher

Das Android SDK-Tool apksigner generiert jetzt die V4-Signaturdatei wenn Sie es mit Standardparametern ausführen. Die V4-Signatur kann auf die gleiche Weise deaktiviert werden. wie die anderen Signatursysteme. Es kann auch prüfen, ob die v4-Signatur gültig sein.

adb erwartet, dass die APK-Datei neben der APK-Datei vorhanden ist, wenn Ausführen des Befehls adb install --incremental
Außerdem wird die .idsig-Datei verwendet, um die inkrementelle Installation und greift auf eine normale Installation zurück, falls diese fehlt oder ungültig.

Wenn eine Installationssitzung erstellt wird, in der PackageInstaller akzeptiert den ausgemusterten v4-Signatur als separates Argument verwenden, wenn Sie der Sitzung eine Datei hinzufügen. An dieser Stelle wird signing_info als im gesamten Blob. Incfs extrahiert den Root-Hash aus dem Blob.

Wenn der Commit der Installationssitzung durchgeführt wird, führt PackageManagerService Ein ioctl zum Abrufen des Signaturinfo-Blobs aus incfs, parst es und verifiziert der Signatur.

Von der Komponente „Inkrementelle Datenladefunktion“ wird erwartet, dass sie den Merkle-Baumteil streamt der Signatur über die native Data Loader API ein.
package-Service-Shell-Befehl install-incremental akzeptiert die entfernte v4-Signaturdatei mit base64 als Parameter für jeden hinzugefügte Datei. Der entsprechende Merkle-Baum muss in den Befehl stdin

apk_digest

apk_digest ist der erste verfügbare Inhalts-Digest in dieser Reihenfolge:

  1. V3, 1-MB-Block, SHA2-512 (CONTENT_DIGEST_CHUNKED_SHA512),
  2. V3, 4-KB-Block, SHA2-256 (CONTENT_DIGEST_VERITY_CHUNKED_SHA256),
  3. V3, 1-MB-Block, SHA2-256 (CONTENT_DIGEST_CHUNKED_SHA256),
  4. V2, SHA2-512
  5. V2, SHA2-256.

Siehe Längenpräfix Reihe von Signaturen mit Längenpräfix im APK-Signaturschema v3.

<ph type="x-smartling-placeholder">
</ph> APK-Validierungsprozess v4
Abbildung 1: APK-Validierungsprozess Version 4

Validierung und Tests

Validieren Sie die Implementierung mithilfe von Funktions-Unittests und CTS.

  • CtsIncrementalInstallHostTestCases
    • /android/cts/hostsidetests/incrementalinstall

Signaturformat testen

Um das Signaturformat zu testen, richten Sie Entwicklungsumgebung und führen Sie die folgenden manuellen Tests aus:

$ atest PackageManagerShellCommandTest
PackageManagerShellCommandIncrementalTest

Testen des Signaturformats mit dem Android SDK (ADB und apksigner)

Wenn Sie das Signaturformat mit dem Android SDK testen möchten, richten Sie eine Entwicklungsumgebung ein. und stellen sicher, dass Sie die Implementierung IncFS Flashe dann den Build auf einem physischen Zielgerät oder Emulator. Du brauchst um ein vorhandenes APK zu generieren oder abzurufen und anschließend einen Signaturschlüssel zur Fehlerbehebung zu erstellen. Signieren und installieren Sie zuletzt das APK mit dem v4-Signaturformat. aus dem Ordner "build-tools" aus.

Zeichen

$ ./apksigner sign --ks debug.keystore game.apk

Installieren

$ ./adb install game.apk

Wo finde ich diese Tests?

/android/cts/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java