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 der APK berechnet wird. Es folgt genau der Struktur des fs-verity-Hashbaums (z. B. Auffüllen des Salzes mit Nullen und Auffüllen des letzten Blocks mit Nullen). Android 11 speichert die Signatur in einer separaten Datei, <apk name>.apk.idsig
Eine v4-Signatur erfordert eine ergänzende v2- oder v3 -Signatur.
Datei Format
Alle numerischen Felder sind in Little Endian. Alle Felder belegen genau die Anzahl von Bytes wie ihre sizeof()
, keine implizite Auffüllung oder Ausrichtung hinzugefügt.
Unten ist eine Hilfsstruktur, um die Definitionen zu vereinfachen.
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 };
hashing_info
sind die Parameter, die für die Hash-Baum-Generierung verwendet werden, + der 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; };
-
apk_digest
stammt aus dem v3-Signaturblock der APK oder, falls nicht vorhanden, aus dem v2-Block (siehe apk_digest )
Um einen signature
zu erstellen und zu verifizieren, müssen die folgenden Daten in ein binäres Blob serialisiert und als signierte Daten an den Signatur-/Verifizierungsalgorithmus übergeben werden:
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; };
-
merkle_tree
ist der gesamte Merkle-Baum der APK, berechnet wie in der fs-verity- Dokumentation beschrieben.
Produzenten und Konsumenten
apksigner
Android SDK-Tool generiert jetzt die v4-Signaturdatei, wenn Sie es mit Standardparametern ausführen. Die v4-Signierung kann auf die gleiche Weise wie die anderen Signaturschemata deaktiviert werden. Es kann auch überprüfen, ob die v4-Signatur gültig ist.
adb
erwartet, dass die Datei .apk.idsig neben der .apk-Datei vorhanden ist, wenn der Befehl adb install --incremental
ausgeführt wird
Es wird auch die .idsig-Datei verwenden, um standardmäßig eine inkrementelle Installation zu versuchen, und auf eine reguläre Installation zurückgreifen, wenn sie fehlt oder ungültig ist.
Wenn eine Installationssitzung erstellt wird, akzeptiert die neue Streaming-Installations-API im PackageInstaller
die entfernte v4-Signatur als separates Argument, wenn der Sitzung eine Datei hinzugefügt wird. An diesem Punkt wird signing_info
als ganzes Blob an incfs übergeben. Incfs extrahiert Root-Hash aus dem Blob.
Wenn die Installationssitzung festgeschrieben wird, führt PackageManagerService ein ioctl aus, um das signing_info-Blob von incfs abzurufen, es zu analysieren und die Signatur zu überprüfen.
Es wird erwartet, dass die inkrementelle Data Loader-Komponente den Merkle-Baum-Teil der Signatur über die native Data Loader-API streamt.
Der package
-Shell-Befehl install-incremental
akzeptiert die entfernte v4-Signaturdatei, die als Base64 codiert ist, als Parameter für jede hinzugefügte Datei. Der entsprechende Merkle-Baum muss in die stdin
des Befehls gesendet werden.
apk_digest
apk_digest
ist der erste verfügbare Content Digest in der folgenden Reihenfolge:
- V3, 1 MB Block, SHA2-512 (CONTENT_DIGEST_CHUNKED_SHA512),
- V3, 4-KB-Block, SHA2-256 (CONTENT_DIGEST_VERITY_CHUNKED_SHA256),
- V3, 1 MB Block, SHA2-256 (CONTENT_DIGEST_CHUNKED_SHA256),
- V2, SHA2-512,
- V2, SHA2-256.
Siehe Sequenz mit Längenpräfix von Signaturen mit Längenpräfix in APK Signature Scheme v3.

Validierung und Prüfung
Validieren Sie die Implementierung mit Feature Unit Tests und CTS.
-
CtsIncrementalInstallHostTestCases
- /android/cts/hostsidetests/incrementalinstall
Testen des Signaturformats
Richten Sie zum Testen des Signaturformats eine Entwicklungsumgebung ein und führen Sie die folgenden manuellen Tests durch:
$ atest PackageManagerShellCommandTest
PackageManagerShellCommandIncrementalTest
Testen des Signaturformats mit Android SDK (ADB und apksigner)
Um das Signaturformat mit Android SDK zu testen, richten Sie eine Entwicklungsumgebung ein und stellen Sie sicher, dass Sie die Implementierung von IncFS abgeschlossen haben. Flashen Sie dann den Build auf einem physischen Zielgerät oder Emulator. Sie müssen ein vorhandenes APK generieren oder abrufen und dann einen Debug-Signaturschlüssel erstellen . Abschließend signieren und installieren Sie die apk mit v4-Signaturformat aus dem build-tools-Ordner.
Schild
$ ./apksigner sign --ks debug.keystore game.apk
Installieren
$ ./adb install game.apk
Wo sind diese Tests zu finden?
/android/cts/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java