Android 11 prend en charge un schéma de signature compatible avec le streaming avec le schéma de signature APK v4. La signature v4 est basée sur l'arbre de hachage Merkle calculé sur tous les octets de l'APK. Il suit exactement la structure de l'arbre de hachage fs-verity (par exemple, zéro remplissage du sel et zéro remplissage du dernier bloc). Android 11 stocke la signature dans un fichier séparé, <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 petit-boutiste. Tous les champs occupent exactement le nombre d'octets correspondant à leur sizeof()
, sans remplissage ni alignement implicite ajouté.
Vous trouverez ci-dessous une structure 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 };
hashing_info
correspond aux paramètres utilisés pour la génération de l'arbre de hachage + 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 la structure suivante :
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
est extrait du bloc de signature v3 de l'APK, ou, s'il n'est pas présent, du bloc v2 (voir apk_digest )
Pour créer et vérifier un code signature
, il faut sérialiser les données suivantes dans un blob binaire et les transmettre à l'algorithme de signature/vérification 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' ensemble de l'arborescence Merkle de l'APK, calculé comme décrit dans la documentation fs-verity .
Producteurs et consommateurs
L'outil apksigner
Android SDK 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 schémas 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 .apk lors de l'exécution de la commande adb install --incremental
Il utilisera également le fichier .idsig pour essayer une installation incrémentielle par défaut et reviendra à une installation standard s'il est manquant ou invalide.
Lorsqu'une session d'installation est créée, la nouvelle API d'installation en streaming dans PackageInstaller
accepte la signature v4 supprimée comme argument distinct lors de l'ajout d'un fichier à la session. À ce stade, signing_info
est transmis à incfs dans son ensemble. Incfs extrait le hachage racine du blob.
Lorsque la session d'installation est en cours de validation, PackageManagerService effectue un ioctl pour récupérer le blob signature_info à partir d'incfs, l'analyse et vérifie la signature.
Le composant Incremental Data Loader devrait diffuser la partie de l'arborescence Merkle de la signature via l'API native du chargeur de données.
La commande shell du service package
install-incremental
accepte le fichier de signature v4 supprimé codé en base64 comme paramètre pour chaque fichier ajouté. L'arborescence Merkle correspondante doit être envoyée dans le stdin
de la commande.
apk_digest
apk_digest
est le premier résumé 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.
Consultez la séquence de signatures avec préfixe de longueur dans APK Signature Scheme v3.
![processus de validation apk v4](https://source.android.com/static/docs/security/images/apk-validation-process-v4.png?authuser=6&hl=fr)
Validation et tests
Validez la mise en œuvre à l’aide des tests unitaires de 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
Test du 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 d' IncFS . Flashez ensuite la version sur un périphérique physique ou un émulateur cible. Vous devez 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.
Signe
$ ./apksigner sign --ks debug.keystore game.apk
Installer
$ ./adb install game.apk
Où peut-on trouver ces tests ?
/android/cts/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java