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 de demandeur. Pour cela, vous devez 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 de 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.

Prérequis pour la vérification

Avant de vérifier un APK extrait, les outils suivants doivent être installés sur votre ordinateur :

Android Debug Bridge (ADB)

ADB est un outil qui communique avec un appareil Android. Il est disponible sur le site Web SDK Android 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 SDK Android Build Tools 26.0.2 et versions ultérieures.

Golang

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

Outil de vérification de la preuve d'inclusion

Nous publions un module Go nommé verifier dans le dépôt GitHub android-binary-transparency. Cet outil interroge le journal de transparence des APK propriétaires de Google pour vérifier si un package est inclus.

Pour utiliser cet outil, clonez d'abord le dépôt sur votre ordinateur local :

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

Le code source de l'outil de vérification se trouve dans le dépôt android-binary-transparency.

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 fractionné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 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 prérequis) 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 fractionné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 d'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 de les énumérer 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 sa sortie directement à 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é, une sortie semblable à celle-ci devrait 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é à côté d'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 ainsi qu'il est conforme aux affirmations du journal.