Cette page décrit différentes méthodes permettant de s'assurer que l'APK installé sur votre appareil Android correspond à l'affirmation faite dans le modèle du demandeur. Cela implique d'extraire l'APK en question de votre appareil, de vérifier l'intégrité de son code et d'effectuer une preuve d'inclusion du journal sur l'artefact extrait.
Procédure de validation
Un journal de transparence est implémenté avec un arbre de Merkle constitué de hachages. Un nœud feuille contient des données, et un nœud parent contient le hachage de ses enfants.
Fondamentalement, deux calculs sont effectués sur l'arbre de Merkle pour vérifier la propriété d'inviolabilité des journaux de transparence : la preuve d'inclusion et la preuve de cohérence. Le premier prouve que le journal inclut une entrée correspondant à une version d'APK spécifique. L'entrée de journal inclut un hachage, qui correspond au résumé SHA256 du jeton de signature du code sous la forme d'un jeton Web JSON (JWT), qui peut être obtenu à partir des APK correspondants. Ce dernier prouve que lorsque de nouvelles entrées sont ajoutées à l'arbre, le nouveau point de contrôle est (cryptographiquement) cohérent avec la version précédente de l'arbre.
Pour valider un fichier APK couvert, effectuez un test de preuve d'inclusion basé sur un point de contrôle observé. Notez que nous prévoyons d'intégrer ce journal à un réseau de témoins public à l'aide d'un protocole de témoin standardisé. Cela fournira un point de contrôle attesté, ce qui garantit la cohérence du journal.
Si vous souhaitez vous assurer que l'APK dont vous disposez sur votre appareil est conforme à l'affirmation faite dans le modèle du demandeur, consultez l'article ci-dessous.
Preuve d'inclusion
Un utilisateur Android peut vérifier qu'un APK couvert sur son appareil figure dans le journal en extrayant d'abord l'APK et ses métadonnées pertinentes, puis en comparant le hachage racine recalculé avec le hachage racine contenu dans le point de contrôle publié. Si elles correspondent, l'utilisateur Android peut être assuré de bénéficier de certaines protections décrites dans le modèle de menaces.
Vérifier l'inclusion d'un fichier APK dans un journal
Comme décrit précédemment, la liste des APK actuellement couverts est disponible sur la page Vue d'ensemble.
Conditions préalables à la validation
Avant de vérifier que le fichier APK que vous venez d'extraire de votre appareil est conforme à notre demande, vous aurez besoin des outils suivants. Installez-les à partir d'un ordinateur connecté au réseau.
Android Debug Bridge (ADB)
ADB est un outil qui communique avec un appareil Android. Il est disponible sur le site Web d'Android SDK Platform-Tools.
AAPT2
AAPT2 (Android Asset Packaging Tool) est un outil de compilation utilisé pour compiler et empaqueter les ressources d'une application Android. Il est disponible en tant qu'outil autonome dans les outils de compilation du SDK Android 26.0.2 et versions ultérieures.
bundletool
bundletool est un outil utilisé pour créer un Android App Bundle (AAB). Il peut également être utilisé pour convertir un AAB en APK pouvant être installés sur des appareils.
Vous pouvez le télécharger sur GitHub.
Outil de validation des preuves d'inclusion
Il s'agit d'un module Go que nous avons publié dans un dépôt Git au sein du Projet Android Open Source (AOSP) nommé avb.
Il est capable d'interroger le journal de transparence de l'APK des services système de Google et d'indiquer si un package est inclus dans le journal.
Vous trouverez un exemple d'utilisation dans une section ultérieure.
Pour télécharger cet outil, vous devez d'abord cloner le dépôt avb.
computer:~$ git clone https://android.googlesource.com/platform/external/avb
Le code source du vérificateur se trouve dans tools/transparency/verify au sein du dépôt avb.
Construire une charge utile pour la validation
Pour vérifier que l'APK que vous avez extrait de votre appareil correspond à nos affirmations, vous devez créer une charge utile de journal à partir des informations dérivées de l'APK.
Avant de commencer, assurez-vous que adb peut être utilisé sur votre appareil en activant le débogage adb sur votre appareil.
Ensuite, localisez l'emplacement où le fichier APK est installé sur votre appareil. Pour les besoins de ce guide, nous utiliserons l'APK Android System Key Verifier (com.google.android.contactkeys) comme exemple pratique.
computer:~$ adb shell pm list packages -f | grep contactkeys
package:/data/app/~~i5WYSO4PuAAv798-eHdM7A==/com.google.android.contactkeys-PQCKjnn7xDqjeVhcUDibBA==/base.apk=com.google.android.contactkeys
Si le fichier APK Android System Key Verifier est installé sur votre appareil, la commande ci-dessus renverra un chemin d'accès indiquant où il est installé sur votre appareil. Sinon, aucun résultat ne s'affichera.
Ensuite, téléchargez l'APK depuis votre appareil Android sur l'ordinateur que vous utilisez à l'aide de cette commande (notez que l'emplacement réel et le nom de fichier APK sur votre appareil peuvent varier) :
computer:~$ mkdir -p /tmp/testdir && cd /tmp/testdir
computer:/tmp/testdir$ adb pull /data/app/~~i5WYSO4PuAAv798-eHdM7A==/com.google.android.contactkeys-PQCKjnn7xDqjeVhcUDibBA==/base.apk ./contactkeys_candidate.apk
Pour obtenir et valider le nom de package de l'APK que vous venez de télécharger, vous devez d'abord décompresser l'APK, car il s'agit en fait d'un type spécial de fichier ZIP.
computer:/tmp/testdir$ mkdir extracted && unzip contactkeys_candidate.apk -d extracted/
Cette étape décompresse tous les fichiers qui composent l'APK. Le nom et la version du package se trouvent dans le fichier manifeste de l'APK, qui se trouve généralement dans un fichier nommé AndroidManifest.xml.
Toutefois, le fichier manifeste obtenu est au format binaire, qui n'est pas lisible par l'utilisateur.
Pour convertir le fichier XML binaire en un format lisible, nous utilisons l'outil aapt2 installé précédemment (comme indiqué dans la section Prérequis).
computer:/tmp/testdir$ aapt2 dump badging ./contactkeys_candidate.apk
package: name='com.google.android.contactkeys' versionCode='7805' versionName='1.219.791156583' platformBuildVersionName='Baklava' platformBuildVersionCode='36' compileSdkVersion='36' compileSdkVersionCodename='Baklava'
D'après le résultat ci-dessus, nous pouvons être sûrs que le nom du package de cet APK est com.google.android.contactkeys et que le numéro de version (versionCode) est 1413.
Nous allons maintenant rechercher la signature de transparence du code dans l'APK. Il doit s'agir d'un fichier nommé code_transparency_signed.jwt contenu dans le dossier META-INF parmi les autres fichiers extraits de l'APK.
computer:/tmp/testdir$ sha256sum extracted/META-INF/code_transparency_signed.jwt
1779a2aee029112c2c9bfc9390b9678f3e5f4595b39705e8528dd522e8042f11 code_transparency_signed.jwt
Avec cette chaîne de hachage, nous disposons désormais de toutes les informations nécessaires pour reconstituer une charge utile de journal selon le format décrit dans la section Contenu du journal. Dans cet exemple, une charge utile de journal correspondante doit ressembler à ce qui suit :
1779a2aee029112c2c9bfc9390b9678f3e5f4595b39705e8528dd522e8042f11
SHA256(Signed Code Transparency JWT)
com.google.android.contactkeys
1143
Notez également le caractère de nouvelle ligne après la version du package.
Vous pouvez enregistrer le contenu dans un fichier, par exemple payload.txt. Cela vous sera utile lorsque vous effectuerez le test de preuve d'inclusion plus tard.
Vérifier l'authenticité de la signature du code APK
Nous devons maintenant vérifier l'authenticité du jeton de signature de code intégré à l'APK. Pour ce faire, nous utilisons bundletool et la clé publique de la paire de clés qui a été utilisée pour la signer en premier lieu. Elles sont publiées dans chaque section des APK respectifs. En supposant que vous ayez enregistré le certificat de clé publique (par exemple, pour Android System Key Verifier) dans un fichier nommé signing_cert_pubkey.pem, suivez le guide ci-dessous pour effectuer la vérification de la signature du code.
Commencez par créer une archive ZIP et ajoutez-y le fichier APK candidat.
computer:/tmp/testdir$ zip -u test.zip contactkeys_candidate.apk
zip warning: test.zip not found or empty
adding: contactkeys_candidate.apk (deflated 58%)
computer:/tmp/testdir$ file test.zip
test.zip: Zip archive data, at least v2.0 to extract, compression method=deflate
Nous sommes maintenant prêts à utiliser la commande check-transparency de bundletool pour vérifier si la signature de code intégrée dans l'APK candidat correspond à celle qui est publiée.
computer:/tmp/testdir$ java -jar BUNDLETOOL_INSTALL_PATH/bundletool-all-version.jar check-transparency \
--mode=apk \
--apk-zip=test.zip \
--transparency-key-certificate=signing_cert_pubkey.pem
APK signature is valid. SHA-256 fingerprint of the apk signing key certificate (must be compared with the developer's public key manually): D9 E1 73 5B 2A 39 51 27 3A 87 35 B7 66 9E F1 9E F5 3A F1 C1 27 5C BA 31 39 3C 18 40 8B 03 79 D0
Code transparency signature verified for the provided code transparency key certificate.
Code transparency verified: code related file contents match the code transparency file.
Vous devez vous assurer que le résultat de la commande ci-dessus indique que la signature de transparence du code et la transparence du code sont vérifiées.
Si ce n'est pas le cas (par exemple, si vous voyez une sortie telle que Code transparency verification failed because the provided public key
certificate does not match the transparency file), cela signifie que l'intégrité du code de l'APK en question peut potentiellement être compromise et que vous ne devez pas faire confiance à l'APK.
N'oubliez pas de vérifier que vous les comparez au bon certificat de clé publique.
Sinon, si tout le reste est correct, cela signifie que l'authenticité de la signature du code est validée pour l'APK que vous validez.
Vérifier l'inclusion du package (preuve d'inclusion)
À l'aide de la charge utile que vous avez créée précédemment, vous êtes maintenant prêt à tester si le package en question a été inclus dans le journal de transparence.
Un outil de preuve d'inclusion a été publié dans le dépôt avb du projet Android Open Source. Pour l'exécuter :
computer:external/avb/tools/transparency/verify$ PAYLOAD_PATH=PATH_TO_PAYLOAD_DIR/payload.txt
computer:external/avb/tools/transparency/verify$ go build cmd/verifier/verifier.go
computer:external/avb/tools/transparency/verify$ ./verifier --payload_path=${PAYLOAD_PATH} --log_type=google_system_apk
Le vérificateur utilise le point de contrôle correspondant et le contenu du journal (disponible dans le répertoire des tuiles) pour vérifier que la charge utile de votre APK figure dans le journal de transparence, ce qui confirme qu'elle a bien été publiée par Google.
Le résultat de la commande est écrit dans stdout :
OK. inclusion check success!si le code du package est inclus dans le journal,FAILUREsi ce n'est pas le cas.