Android 11 unterstützt ein streamingkompatibles Signaturschema mit dem APK-Signaturschema v4. Die V4-Signatur basiert auf dem Merkle-Hash-Baum, der über alle Bytes des APK berechnet wird. Er folgt genau der Struktur des fs-verity-Hashbaums (z. B. Null-Padding des Salzes und des letzten Blocks). Unter Android 11 wird die Signatur in einer separaten Datei gespeichert. <apk name>.apk.idsig
Eine V4-Signatur erfordert eine ergänzende V2- oder V3-Signatur.
Dateiformat
Alle numerischen Felder sind im Little-Endian-Format. Alle Felder belegen genau die Anzahl von Byte wie ihre sizeof()
, es wird kein impliziter Padding oder keine implizite Ausrichtung hinzugefügt.
Unten finden Sie eine Hilfsstruktur, die die Definitionen vereinfacht.
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-Baumgenerierung verwendet werden, und der Wurzel-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
wird aus dem V3-Signaturblock des APK oder, falls nicht vorhanden, aus dem V2-Block übernommen (siehe apk_digest).
Zum Erstellen und Verifizieren eines signature
-Codes müssen die folgenden Daten in einen Binär-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 des APK, der wie in der fs-verity-Dokumentation beschrieben berechnet wird.
Produzenten und Verbraucher
apksigner
Das Android SDK-Tool generiert jetzt die V4-Signaturdatei, wenn Sie es mit den Standardparametern ausführen. Die V4-Signatur kann auf die gleiche Weise wie die anderen Signaturschemata deaktiviert werden. Außerdem kann damit geprüft werden, ob die V4-Signatur gültig ist.
adb
erwartet, dass die Datei „.apk.idsig“ neben der Datei „.apk“ vorhanden ist, wenn der Befehl adb install --incremental
ausgeführt wird.
Außerdem wird die Datei „.idsig“ standardmäßig für die inkrementelle Installation verwendet. Wenn sie fehlt oder ungültig ist, wird auf eine reguläre Installation zurückgegriffen.
Wenn eine Installationssitzung erstellt wird, akzeptiert die neue Streaming-Installations-API in der PackageInstaller
die entfernte V4-Signatur als separates Argument, wenn der Sitzung eine Datei hinzugefügt wird.
An diesem Punkt wird signing_info
als ganzer Blob an incfs übergeben. Incfs extrahiert den Root-Hash aus dem Blob.
Wenn die Installationssitzung verbindlich wird, führt PackageManagerService einen ioctl aus, um den signing_info
-Blob aus incfs abzurufen, ihn zu parsen und die Signatur zu überprüfen.
Die Komponente „Incremental Data Loader“ soll den Merkle-Baum-Teil der Signatur über die native API des Data Loaders streamen.Der
package
-Dienst-Shellbefehl install-incremental
nimmt die entfernbare V4-Signaturdatei, die als Base64 codiert ist, als Parameter für jede hinzugefügte Datei an. Der entsprechende Merkle-Baum muss an die stdin
des Befehls gesendet werden.
apk_digest
apk_digest
ist der erste verfügbare Inhalts-Digest in folgender Reihenfolge:
- V3, 1-MB-Block, SHA2-512 (CONTENT_DIGEST_CHUNKED_SHA512),
- V3, 4KB-Block, SHA2-256 (CONTENT_DIGEST_VERITY_CHUNKED_SHA256),
- V3, 1-MB-Block, SHA2-256 (CONTENT_DIGEST_CHUNKED_SHA256),
- V2, SHA2-512,
- V2, SHA2-256.
Weitere Informationen finden Sie im APK-Signaturschema 3 unter Abfolge von Signaturen mit Längenpräfix.

Validierung und Tests
Validieren Sie die Implementierung mithilfe von Feature-Unit-Tests und CTS.
CtsIncrementalInstallHostTestCases
- /android/cts/hostsidetests/incrementalinstall
Signaturformat testen
Wenn Sie das Signaturformat testen möchten, richten Sie eine Entwicklungsumgebung ein und führen Sie die folgenden manuellen Tests aus:
$ atest PackageManagerShellCommandTest
PackageManagerShellCommandIncrementalTest
Signaturformat mit dem Android SDK (ADB und apksigner) testen
Wenn Sie das Signaturformat mit dem Android SDK testen möchten, richten Sie eine Entwicklungsumgebung ein und prüfen Sie, ob Sie die Implementierung von IncFS abgeschlossen haben. Flashen Sie dann das Build auf einem Zielgerät oder Emulator. Sie müssen ein APK generieren oder ein vorhandenes APK abrufen und dann einen Debug-Signaturschlüssel erstellen. Signieren und installieren Sie die APK schließlich mit dem Signaturformat v4 aus dem Ordner „build-tools“.
Unterschreiben
$ ./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