Validation complète de la transparence des applications de produits Google

Cette page explique comment vérifier que l'APK ou l'APEX installé sur votre appareil Android correspond aux affirmations faites dans le modèle du demandeur. Le processus consiste à extraire l'APK de votre appareil et à effectuer une preuve d'inclusion du journal sur l'artefact extrait.

Processus de vérification

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.

Deux calculs fondamentaux permettent de vérifier la propriété d'inviolabilité des journaux de transparence : la preuve d'inclusion et la preuve de cohérence. La preuve d'inclusion confirme que le journal inclut une entrée pour une version d'APK spécifique. Cette entrée de journal contient un hachage, qui correspond au condensé SHA256 du fichier APK installé sur l'appareil. La preuve de cohérence garantit que lorsque de nouvelles entrées sont ajoutées, le nouveau point de contrôle reste cryptographiquement cohérent avec les versions précédentes de l'arbre (ou que l'arbre n'a pas été falsifié). Dans ce guide, nous nous concentrons sur le processus de calcul de la preuve d'inclusion, tout en nous appuyant sur des témoins pour effectuer en continu une preuve de cohérence par rapport aux derniers points de contrôle.

Pour vérifier un APK couvert, effectuez une preuve d'inclusion par rapport à un point de contrôle témoin. 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é. Cette intégration fournira des points de contrôle témoins, garantissant la cohérence du journal.

Pour vérifier que les applications Google de votre appareil sont conformes aux affirmations faites dans le modèle du demandeur, procédez comme suit.

Preuve d'inclusion

Vous pouvez vérifier qu'un APK couvert sur votre appareil se trouve dans le journal en l'extrayant, en calculant son hachage et en utilisant une preuve d'inclusion pour vérifier si ce hachage existe dans le point de contrôle publié. Une preuve d'inclusion réussie offre une assurance contre les risques décrits dans le modèle de menace, confirmant que l'application est une application Google légitime.

Comment vérifier l'inclusion d'un APK dans le journal

Toute application se présentant comme une application Google propriétaire peut être vérifiée par rapport à ce journal.

Conditions préalables pour la validation

Avant de vérifier que l'artefact (micrologiciel ou APK) est conforme à l'affirmation, assurez-vous que les outils suivants sont disponibles sur un ordinateur connecté au réseau. Selon la cible de vérification, vous n'aurez peut-être pas besoin de tous ces outils.

Golang

L'outil de vérification est écrit en Go. Pour le compiler, installez Go 1.24 ou version ultérieure à partir du site Go.

Android Debug Bridge (ADB)

ADB est un outil qui communique avec un appareil Android pour inspecter l'image ou extraire des APK. Il est disponible sur le site Web SDK Android Platform Tools website.

Outil de vérification de la preuve d'inclusion

L'outil de vérification de la preuve d'inclusion est un module Go qui interroge le journal de transparence et indique si un artefact est inclus dans le journal. Il est publié dans le dépôt GitHub android-binary-transparency à l'adresse https://github.com/android/android-binary-transparency/tree/main.

Pour cloner le dépôt AOSP avb :

computer:~$ git clone https://android.googlesource.com/platform/external/avb

Pour cloner le dépôt GitHub android-binary-transparency :

computer:~$ git clone https://github.com/android/android-binary-transparency

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 version 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 vérifier les signatures de code APK. Il peut être téléchargé depuis GitHub.

wget ou curl

wget et curl sont des outils qui peuvent être utilisés pour récupérer ou télécharger des fichiers depuis Internet. Assurez-vous que l'un de ces outils est installé, car les scripts de vérification peuvent en dépendre.

Avbtool

avbtool est utilisé pour calculer le condensé VBMeta des images d'usine et la vérification des binaires. Après avoir cloné le dépôt avb (comme indiqué dans la section Outil de vérification de la preuve d'inclusion ), avbtool.py se trouve dans le répertoire avb cloné. Vous devez ajouter ce répertoire à votre variable d'environnement $PATH.

computer:~$ PATH=$PATH:DIRECTORY_CONTAINING_AVBTOOL

Fbpacktool

fbpacktool est un script Python utilisé pour décompresser des composants individuels dans Pixel's bootloader.img. Vous n'en avez pas besoin si vous vérifiez des APK. Cet outil est important, car il permet à avbtool.py de découvrir les images requises pour la vérification.

fbpacktool nécessite Python 3.6 ou version ultérieure et le PyYAML (par exemple, python3 -m pip install pyyaml).

Pour utiliser cet outil, vous devez télécharger les six scripts Python suivants dans le répertoire où se trouve votre avbtool.py, rendre fbpacktool.py exécutable, et créer un lien symbolique nommé fbpacktool vers fbpacktool.py pour plus de commodité.

Si vous disposez de wget :

computer:dir_to_avbtool$ wget https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/fbpacktool.py \
https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/fbpack.py \
https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/packedstruct.py \
https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/xmlparser.py \
https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/xmlserializer.py \
https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/yamlparser.py
computer:dir_to_avbtool$ chmod +x fbpacktool.py
computer:dir_to_avbtool$ ln -s fbpacktool.py fbpacktool

Si vous disposez de curl :

computer:dir_to_avbtool$ curl -LO https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/fbpacktool.py
computer:dir_to_avbtool$ curl -LO https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/fbpack.py
computer:dir_to_avbtool$ curl -LO https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/packedstruct.py
computer:dir_to_avbtool$ curl -LO https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/xmlparser.py
computer:dir_to_avbtool$ curl -LO https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/xmlserializer.py
computer:dir_to_avbtool$ curl -LO https://developers.google.com/android/binary_transparency/tools/pixel/fbpacktool/yamlparser.py
computer:dir_to_avbtool$ chmod +x fbpacktool.py
computer:dir_to_avbtool$ ln -s fbpacktool.py fbpacktool

OpenSSL

openssl permet d'effectuer diverses opérations de chiffrement à l'aide du terminal dans le workflow de vérification. Assurez-vous qu'il est installé sur votre système. Vous pouvez vérifier sur votre terminal en exécutant la commande suivante et en vous assurant que le résultat renvoyé n'est pas vide :

computer:~$ which openssl
/usr/bin/openssl

Créer une charge utile pour la vérification

Pour vérifier l'APK extrait, vous devez créer une charge utile de journal à l'aide d'informations dérivées de l'APK lui-même.

Avant de commencer, activez le débogage USB sur votre appareil pour autoriser les adb connexions.

Ensuite, recherchez l'APK installé sur votre appareil. Ce guide utilise l' APK des services Google Play (com.google.android.gms) comme exemple de travail.

adb shell pm path com.google.android.gms

La sortie obtenue doit ressembler à ceci :

computer:~$ adb shell pm path com.google.android.gms
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/base.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_CronetDynamite_installtime.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_DynamiteLoader_installtime.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_DynamiteModulesA_installtime.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_DynamiteModulesC_installtime.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_GoogleCertificates_installtime.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_MapsDynamite_installtime.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_MeasurementDynamite_installtime.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_config.en.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_config.xxhdpi.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_maps_core_dynamite_ondemand.apk

Cette sortie indique qu'un APK de base et plusieurs APK divisés sont installés pour com.google.android.gms sur votre appareil. Le nombre exact d'APK divisés varie en fonction de la configuration de votre appareil. Chaque APK divisé partage le même nom de package et le même code de version que l'APK de base.

Téléchargez les APK listés depuis votre appareil Android vers votre ordinateur à l'aide de la commande suivante (notez que les chemins d'accès réels aux fichiers peuvent varier) :

mkdir -p /tmp/testdir/gms && cd /tmp/testdir/gms && \
adb shell pm path com.google.android.gms | cut -d':' -f2 | tr -d '\r' | xargs -n1 adb pull

Pour vérifier le nom de package et la version des APK téléchargés, vous devez inspecter leur fichier manifeste (AndroidManifest.xml).

Étant donné que le fichier manifeste d'un APK est au format binaire, utilisez l'outil aapt2(installé lors de l'étape des conditions préalables) pour extraire et lire les informations directement à partir de l'APK :

computer:/tmp/testdir/gms$ aapt2 dump badging ./base.apk
package: name='com.google.android.gms' versionCode='260834035' versionName='26.08.34 (260400-876566425)' platformBuildVersionName='Baklava' platformBuildVersionCode='36' compileSdkVersion='36' compileSdkVersionCodename='Baklava'
minSdkVersion:'35'
targetSdkVersion:'36'
...

Vous devez répéter cette étape pour obtenir les informations pertinentes jusqu'à ce que vous ayez pris en compte tous les APK divisés installés sur votre appareil.

La sortie confirme que le nom de package de l'APK est com.google.android.gms et que son numéro de version (versionCode) est 260834035.

Ensuite, calculez le hachage cryptographique de chaque APK :

computer:/tmp/testdir/gms$ sha256sum *.apk
66aa2d7b9752cdd61065b55c8e16739d8367fa18a0f1c8c84122369f86958f1a  base.apk
c20754aee886cc55a9de91ee15c623c59d94ad22b7e435a1a48afc43cf1a106c  split_config.en.apk
68c09b63a1262e0d34020c139bc77deff3c32bd2b01177abac64790a62fb3be6  split_config.xxhdpi.apk
cd746820c27babd855fa5daea6fabcdf7b44abf3060bc547adc4219212410af0  split_CronetDynamite_installtime.apk
512ee48b60fdb0787a17f84a7dc448fdbf885b2b86a9cb50525d4c22d561b0f1  split_DynamiteLoader_installtime.apk
9e0c74bdc75c50c80d4e2e580a7eda6b8391423ab1161645f41ec6cadc07d678  split_DynamiteModulesA_installtime.apk
955780ac01f59b98bd9be12968f3824ad71b762620f7bf223c569c1a6ab7056c  split_DynamiteModulesC_installtime.apk
34c4a2e32d31554d55fc1519e2cfc3ed5027a090fb29b54cfc99f42d1da43bc5  split_GoogleCertificates_installtime.apk
475e18dde92472cde9d8300c082b6dc269613db03398bcd9d1987dff3e68f7b5  split_maps_core_dynamite_ondemand.apk
f83faf40f08bc13f4879302e01c08c863ca2304b4b4e7c9eaf8cd1e869bb6573  split_MapsDynamite_installtime.apk
ec6d854ddda6cd1ba2ba7af2d9fdf4f28c5c78be8713c64521c785429296738c  split_MeasurementDynamite_installtime.apk

Vous disposez maintenant de toutes les informations nécessaires pour créer une charge utile de journal, au format décrit dans la section Contenu du journal. Si vous sélectionnez un hachage parmi les résultats à titre d'exemple (vous devez vérifier le hachage de chaque APK divisé), la charge utile du journal se présente comme suit :

66aa2d7b9752cdd61065b55c8e16739d8367fa18a0f1c8c84122369f86958f1a
SHA256(APK)
com.google.android.gms
260834035

Assurez-vous d'inclure un caractère de saut de ligne à la fin du fichier. Enregistrez ce contenu dans un fichier, tel que payload.txt, pour l'utiliser ultérieurement avec l'outil verifier.

Vérifier l'inclusion du package (preuve d'inclusion)

Une fois votre charge utile créée, vous pouvez vérifier si le package est inclus dans le journal de transparence. Compilez l'outil de preuve d'inclusion à partir du dépôt android-binary-transparency que vous avez cloné précédemment :

go build cmd/verifier/verifier.go

Cela devrait générer un exécutable nommé verifier dans ce répertoire. Exécutez l'outil de vérification, en fournissant le chemin d'accès à votre charge utile et en spécifiant le type de journal :

computer:android-binary-transparency$ PAYLOAD_PATH=PATH_TO_PAYLOAD_DIR/payload.txt
computer:android-binary-transparency$ ./verifier --payload_path=${PAYLOAD_PATH} --log_type=google_1p_apk

L'outil de vérification utilise le point de contrôle et le contenu du journal (à partir du répertoire de tuiles) pour vérifier si votre charge utile APK se trouve dans le journal de transparence, confirmant ainsi qu'elle a été publiée par Google.

La commande génère une sortie vers stderr :

  • OK. inclusion check success! si le package est inclus dans le journal.
  • FAILURE s'il ne l'est pas.

Vérifier automatiquement tous les packages d'un appareil

Étant donné le nombre d'applications Google qui peuvent être préinstallées sur votre appareil, il peut être fastidieux d'énumérer chaque application et d'effectuer des preuves d'inclusion individuellement.

Nous fournissons un autre outil automatisé appelé Uraniborg qui peut détecter et mesurer tous les packages actuellement installés sur votre appareil. Il transmet directement sa sortie à l'outil verifier, ce qui vous permet de découvrir et de vérifier la transparence de toutes les applications de votre appareil en une seule étape.

Pour utiliser ce workflow automatisé, assurez-vous que votre appareil Android est connecté à votre ordinateur via ADB. Le code source Uraniborg est également inclus dans le dépôt android-binary-transparency.

Exécutez le script automate_observation.py situé dans le répertoire scripts/python :

python3 automate_observation.py --pull-all-apks --perform_inclusion_proof_check --verifier_path <path_to_verifier_executable>

Une fois le script terminé, vous devriez voir une sortie semblable à celle-ci :

INFO:automate_observation.py:main(858): SUCCESS! Hubble was successfully deployed and executed on connected device ABCDEFGHN01234.
INFO:automate_observation.py:main(860): Hubble output files can be found at: /Users/user/home/src/android-binary-transparency/uraniborg/scripts/python/results/google/lynx/lynx:16/BP4A.260105.004.E1/14587043:user/release-keys/001

Accédez au répertoire de sortie indiqué par le script. Recherchez le fichier nommé packages_with_inclusion_proof_signal.txt. Ce fichier liste chaque package installé avec un champ inclusion_proof_verified défini sur true ou false. La valeur true indique que le package a été vérifié cryptographiquement par rapport au journal de transparence, confirmant qu'il est conforme aux affirmations du journal.