Android 11 accepte un schéma de signature compatible avec le streaming avec l'APK
Signature Scheme v4. La signature v4 est basée sur l'arbre de hachage Merkle.
calculé pour tous les octets de l'APK. Il suit exactement la structure de l'arborescence de hachage fs-verity (par exemple, remplissage à zéro)
la valeur salt et le remplissage à zéro du dernier bloc). Android 11 stocke la signature
dans un fichier distinct, <apk name>.apk.idsig
une signature v4
nécessite une signature v2 ou v3 complémentaire.
Format de fichier
Tous les champs numériques sont en small-endian. Tous les champs occupent exactement le nombre
d'octets comme sizeof()
, pas de marge intérieure implicite ni
alignement ajouté.
Vous trouverez ci-dessous un struct d'assistance pour simplifier les définitions.
template <class SizeT> struct sized_bytes { SizeT size; byte bytes[size]; };
Contenu du fichier principal:
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
est le paramètre utilisé pour l'arborescence de hachage.
génération + le hachage racine:
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
est le struct suivant:
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
provient du bloc de signature v3 de l'APK, ou, si ce n'est pas le cas présent, à partir du bloc v2 (voir apk_digest)
Pour créer et vérifier un code signature
, vous devez sérialiser
les données suivantes dans un blob binaire et les transmettre au
algorithme de signature / validation en tant que données signées:
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
est l'arborescence Merkle complète de l'APK, calculée comme décrit dans la documentation fs-verity.
Producteurs et consommateurs
apksigner
SDK Tool pour Android génère désormais le fichier de signature v4
si vous l'exécutez avec les paramètres par défaut. La signature v4 peut être désactivée de la même manière
que les autres systèmes de signature. Il peut également vérifier si
la signature v4 est
valide.
adb
s'attend à ce que le fichier .apk.idsig soit présent à côté du fichier .apk lorsque
en exécutant la commande adb install --incremental
Il utilisera également le fichier .idsig pour essayer l'installation incrémentielle en
par défaut, et reviendra à une installation
normale si elle est manquante ou
non valide.
Lorsqu'une session d'installation est créée, la nouvelle API d'installation en streaming
dans PackageInstaller
accepte les valeurs stripped
v4 en tant qu'argument distinct lors de l'ajout d'un fichier à la session.
À ce stade, signing_info
est transmis dans incfs en tant que
blob dans son intégralité. L'outil Incfs extrait le hachage racine de l'objet blob.
Lorsque la session d'installation est validée, PackageManagerService effectue Un ioctl pour récupérer le blob signing_info à partir d'incfs, l'analyser et vérifier la signature.
Le composant Data Loader incrémentiel est censé diffuser la partie de l'arborescence de Merkle.
de la signature via l'API native du chargeur de données.
Commande shell du service package
install-incremental
accepte le fichier de signature v4 tronqué encodé en base64 comme paramètre pour chaque
fichier ajouté. L'arborescence de Merkle correspondante doit être envoyée dans la couche
stdin
récapitulatif_apk
apk_digest
est le premier condensé de contenu disponible dans l'ordre:
- V3, bloc de 1 Mo, SHA2-512 (CONTENT_DIGEST_CHUNKED_SHA512),
- V3, bloc de 4 Ko, SHA2-256 (CONTENT_DIGEST_VERITY_CHUNKED_SHA256),
- V3, bloc de 1 Mo, SHA2-256 (CONTENT_DIGEST_CHUNKED_SHA256),
- V2, SHA2-512
- V2, SHA2-256
Voir avec préfixe de longueur séquence de signatures avec préfixe de longueur dans APK Signature Scheme v3.
<ph type="x-smartling-placeholder">Validation et test
Valider l'implémentation à l'aide de tests unitaires des fonctionnalités et de CTS
CtsIncrementalInstallHostTestCases
- /android/cts/hostsidetests/incrementalinstall
Tester le format de signature
Pour tester le format de signature, configurez un environnement de développement et exécutez les tests manuels suivants:
$ atest PackageManagerShellCommandTest
PackageManagerShellCommandIncrementalTest
Tester le format de signature avec le SDK Android (ADB et apksigner)
Pour tester le format de signature avec le SDK Android, configurez un environnement de développement. et assurez-vous d'avoir terminé la mise en œuvre IncFS : Flashez ensuite le build sur un appareil physique ou un émulateur cible. Vous devez pour générer ou obtenir un APK existant, puis créer une clé de signature de débogage. Enfin, signez et installez l'APK au format de signature v4. à partir du dossier "build-tools".
Signer
$ ./apksigner sign --ks debug.keystore game.apk
Installer
$ ./adb install game.apk
Où trouver ces tests ?
/android/cts/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java