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 revendications 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.

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.

Deux calculs fondamentaux permettent de vérifier la propriété inviolable 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 APK spécifique. Cette entrée de journal contient un hachage, qui correspond au résumé 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'arborescence (ou que l'arborescence n'a pas été falsifiée). 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 permanence une preuve de cohérence par rapport aux derniers points de contrôle.

Pour valider un APK couvert, effectuez une preuve d'inclusion par rapport à un point de contrôle observé. Notez que nous prévoyons d'intégrer ce journal à un réseau de témoins publics à l'aide d'un protocole de témoin standardisé. Cette intégration fournira des points de contrôle observés, garantissant la cohérence du journal.

Pour vérifier que les applications Google sur votre appareil sont conformes aux affirmations faites dans le modèle du demandeur, suivez les étapes ci-dessous.

Preuve d'inclusion

Vous pouvez vérifier qu'un APK couvert sur votre appareil figure dans le journal en extrayant l'APK, 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 permet de se prémunir contre les risques décrits dans le modèle de menace, en confirmant que l'application est une application Google légitime.

Vérifier l'inclusion d'un APK dans un journal

Toute application se présentant comme une application Google propriétaire peut être vérifiée à l'aide de ce journal.

Conditions préalables pour la validation

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

Golang

L'outil de validation 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 d'Android SDK Platform-Tools.

Outil de validation de la preuve d'inclusion

Le vérificateur de 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 avb de l'AOSP :

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 ultérieures.

bundletool

bundletool est un outil utilisé pour créer un Android App Bundle (AAB). Il peut également être utilisé pour valider les signatures de code APK. Vous pouvez le télécharger sur 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 d'avoir installé l'un de ces outils, car les scripts de validation peuvent en dépendre.

Avbtool

avbtool est utilisé pour calculer le condensé VBMeta des images d'usine et vérifier les binaires. Après avoir cloné le dépôt avb (comme indiqué dans la section sur le vérificateur de 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 bootloader.img de Pixel. Vous n'en avez pas besoin si vous validez des APK. Cet outil est important, car il permet à avbtool.py de découvrir les images requises pour la validation.

Pour utiliser cet outil, vous devez télécharger les trois 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 avez wget :

computer:dir_to_avbtool$ wget https://source.android.com/devices/bootloader/tools/pixel/fw_unpack/fbpacktool.py \
https://source.android.com/devices/bootloader/tools/pixel/fw_unpack/fbpack.py \
https://source.android.com/devices/bootloader/tools/pixel/fw_unpack/packedstruct.py
computer:dir_to_avbtool$ chmod +x fbpacktool.py
computer:dir_to_avbtool$ ln -s fbpacktool.py fbpacktool

Si vous avez curl :

computer:dir_to_avbtool$ curl -O https://source.android.com/devices/bootloader/tools/pixel/fw_unpack/fbpacktool.py
computer:dir_to_avbtool$ curl -O https://source.android.com/devices/bootloader/tools/pixel/fw_unpack/fbpack.py
computer:dir_to_avbtool$ curl -O https://source.android.com/devices/bootloader/tools/pixel/fw_unpack/packedstruct.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 cryptographiques à l'aide du terminal dans le workflow de validation. Assurez-vous qu'il est installé sur votre système. Vous pouvez vérifier dans 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

Construire une charge utile pour la validation

Pour valider votre APK extrait, vous devez créer une charge utile de journal à l'aide d'informations provenant de l'APK lui-même.

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

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

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 fractionnés varie en fonction de la configuration de votre appareil. Chaque APK fractionné 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 vos chemins d'accès 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 du package et la version des APK téléchargés, vous devez inspecter leur fichier manifeste (AndroidManifest.xml).

Étant donné que le fichier manifeste à l'intérieur d'un APK est au format binaire, utilisez l'outil aapt2 (installé lors de l'étape des prerequisites) 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 du 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 fichier 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 construire une charge utile de journal, mise en forme comme décrit dans la section Contenu du journal. Si vous sélectionnez un hachage dans les résultats à titre d'exemple (vous devez vérifier le hachage de chaque APK fractionné), la charge utile du journal se présente comme suit :

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

Veillez à inclure un caractère de nouvelle 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)

Maintenant que votre charge utile est construite, vous pouvez vérifier si le package est inclus dans le journal de transparence. Créez 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

Un exécutable nommé verifier devrait alors se trouver dans ce répertoire. Exécutez le vérificateur 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

Le vérificateur utilise le point de contrôle et le contenu du journal (à partir du répertoire des tuiles) pour vérifier si votre charge utile APK figure dans le journal de transparence, ce qui confirme 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 dans le cas contraire.

Validation automatique de tous les packages sur 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 son résultat à l'outil verifier, ce qui vous permet de découvrir et de vérifier la transparence de toutes les applications sur 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é, un résultat semblable à celui-ci doit s'afficher :

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. Une valeur true indique que le package a été vérifié de manière cryptographique par rapport au journal de transparence, ce qui confirme qu'il est conforme aux déclarations du journal.