Verifica completa della trasparenza delle applicazioni di Google

Questa pagina descrive come verificare che l'APK o l'APEX installato sul tuo dispositivo Android corrisponda alle attestazioni effettuate nel modello del richiedente. La procedura prevede l'estrazione dell'APK dal dispositivo e l'esecuzione di una prova di inclusione dei log sull'artefatto estratto.

Procedura di verifica

Un log di trasparenza viene implementato con una struttura ad albero Merkle costituita da hash. Un nodo foglia contiene dati, mentre un nodo padre contiene l'hash dei relativi nodi secondari.

Due calcoli fondamentali verificano la proprietà antimanomissione dei log di trasparenza: la prova di inclusione e la prova di coerenza. La prova di inclusione conferma che il log include una voce per una versione specifica dell'APK. Questa voce di log contiene un hash, ovvero il digest SHA256 del file APK installato sul dispositivo. La prova di coerenza garantisce che, quando vengono aggiunte nuove voci, il nuovo checkpoint rimanga crittograficamente coerente con le versioni precedenti dell'albero (o che l'albero non sia stato manomesso). In questa guida ci concentriamo sul processo di calcolo della prova di inclusione, mentre ci affidiamo ai testimoni per eseguire continuamente la prova di coerenza rispetto agli ultimi checkpoint.

Per verificare un APK coperto, esegui una prova di inclusione rispetto a un checkpoint testimoniato. Tieni presente che prevediamo di integrare questo log con una rete di testimoni pubblici utilizzando un protocollo di testimonianza standardizzato. Questa integrazione fornirà checkpoint verificati, garantendo la coerenza del log.

Per verificare che le app Google sul tuo dispositivo siano conformi alle rivendicazioni effettuate nel modello del richiedente, segui i passaggi riportati di seguito.

Prova di inclusione

Puoi verificare che un APK coperto sul tuo dispositivo sia presente nel log estraendo l'APK, calcolandone l'hash e utilizzando una prova di inclusione per verificare se l'hash esiste nel checkpoint pubblicato. Una prova di inclusione riuscita fornisce garanzia contro i rischi descritti nel modello di minaccia, confermando che l'app è un'app Google legittima.

Come verificare l'inclusione di un APK nel log

Qualsiasi app che dichiara di essere un'app Google proprietaria può essere verificata rispetto a questo log.

Prerequisiti di verifica

Prima di procedere con la verifica che l'artefatto (firmware o APK) sia conforme alla rivendicazione, assicurati che i seguenti strumenti siano disponibili su un computer connesso alla rete. A seconda della destinazione della verifica, potresti non aver bisogno di tutti.

Linguaggio Go

Lo strumento di verifica è scritto in Go. Per crearlo, installa Go 1.24 o versioni successive dal sito di Go.

Android Debug Bridge (ADB)

ADB è uno strumento che comunica con un dispositivo Android per esaminare l'immagine o estrarre gli APK, disponibile sul sito web di Android SDK Platform Tools.

Inclusion Proof verifier

Il programma di verifica della prova di inclusione è un modulo Go che esegue query nel log di trasparenza e indica se un artefatto è incluso nel log. È pubblicato nel repository GitHub android-binary-transparency all'indirizzo https://github.com/android/android-binary-transparency/tree/main

Per clonare il repository AOSP avb:

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

Per clonare il repository GitHub android-binary-transparency:

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

AAPT2

AAPT2 (Android Asset Packaging Tool) è uno strumento di compilazione utilizzato per compilare e pacchettizzare le risorse di un'app per Android. Può essere trovato come strumento autonomo in Android SDK Build Tools versione 26.0.2 e successive.

bundletool

bundletool è uno strumento utilizzato per creare un Android App Bundle (AAB). Può essere utilizzato anche per verificare le firme del codice APK. Può essere scaricato da GitHub.

wget o curl

wget e curl sono strumenti che possono essere utilizzati per recuperare o scaricare file da internet. Assicurati di aver installato uno di questi strumenti, poiché gli script di verifica potrebbero farvi affidamento.

Avbtool

avbtool viene utilizzato per calcolare il digest VBMeta delle immagini di fabbrica e la verifica dei file binari. Dopo aver clonato il repository avb (come mostrato nella sezione del programma di verifica della prova di inclusione), avbtool.py si trova all'interno della directory avb clonata. Devi aggiungere questa directory alla variabile di ambiente $PATH.

computer:~$ PATH=$PATH:DIRECTORY_CONTAINING_AVBTOOL

Fbpacktool

fbpacktool è uno script Python utilizzato per decomprimere i singoli componenti nel bootloader.img di Pixel. Non è necessario se stai verificando gli APK. Questo strumento è importante perché consente a avbtool.py di scoprire le immagini richieste per la verifica.

Per utilizzare questo strumento, devi scaricare i tre script Python seguenti nella directory in cui si trova avbtool.py, rendere eseguibile fbpacktool.py e creare un link simbolico denominato fbpacktool a fbpacktool.py per comodità.

Se hai 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

Se hai 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 consente di eseguire varie operazioni di crittografia utilizzando il terminale nel flusso di lavoro di verifica. Assicurati che sia installato sul tuo sistema. Puoi controllare sul terminale eseguendo il seguente comando e assicurandoti che il risultato restituito non sia vuoto:

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

Creare un payload per la verifica

Per verificare l'APK estratto, devi creare un payload di log utilizzando le informazioni derivate dall'APK stesso.

Prima di iniziare, attiva il debug USB sul tuo dispositivo per consentire le connessioni adb.

Poi, individua l'APK installato sul dispositivo. Questa guida utilizza l'APK di Google Play Services (com.google.android.gms) come esempio pratico.

adb shell pm path com.google.android.gms

Dovresti vedere un output simile al seguente:

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

Questo output indica che sul tuo dispositivo sono installati un APK di base e diversi APK divisi per com.google.android.gms. Il numero esatto di APK suddivisi varia a seconda della configurazione del dispositivo. Ogni APK suddiviso condivide lo stesso nome del pacchetto e lo stesso codice versione dell'APK di base.

Scarica gli APK elencati dal tuo dispositivo Android sul computer utilizzando il seguente comando (tenendo presente che i percorsi dei file effettivi potrebbero variare):

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

Per verificare il nome del pacchetto e la versione degli APK scaricati, devi ispezionare il manifest (AndroidManifest.xml).

Poiché il manifest all'interno di un APK è in formato binario, utilizza lo strumento aapt2 (installato durante il passaggio dei prerequisiti) per estrarre e leggere le informazioni direttamente dall'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'
...

Devi ripetere questo passaggio per ottenere le informazioni pertinenti finché non avrai tenuto conto di tutti gli APK suddivisi installati sul tuo dispositivo.

L'output conferma che il nome del pacchetto dell'APK è com.google.android.gms e il numero di versione (versionCode) è 260834035.

Successivamente, calcola l'hash crittografico di ogni 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

Ora hai tutte le informazioni necessarie per creare un payload di log, formattato come descritto nella sezione Contenuto del log. Selezionando un hash dai risultati come esempio (devi verificare l'hash di ogni APK suddiviso), il payload del log ha il seguente aspetto:

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

Assicurati di includere un carattere di nuova riga alla fine del file. Salva questi contenuti in un file, ad esempio payload.txt, da utilizzare in un secondo momento con lo strumento verifier.

Verifica dell'inclusione del pacchetto (prova di inclusione)

Una volta creato il payload, puoi verificare se il pacchetto è incluso nel log di trasparenza. Crea lo strumento di prova di inclusione dal repository android-binary-transparency che hai clonato in precedenza:

go build cmd/verifier/verifier.go

In questo modo, nella directory dovrebbe essere presente un eseguibile denominato verifier. Esegui il programma di verifica, fornendo il percorso del payload e specificando il tipo di log:

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

Il programma di verifica utilizza il checkpoint e i contenuti del log (dalla directory dei riquadri) per controllare se il payload APK si trova nel log di trasparenza, confermando che è stato pubblicato da Google.

Il comando genera l'output in stderr:

  • OK. inclusion check success! se il pacchetto è incluso nel log.
  • FAILURE se non lo è.

Verifica automatica di tutti i pacchi in un dispositivo

Dato il numero di app Google che potrebbero essere preinstallate sul tuo dispositivo, enumerare ogni app ed eseguire singolarmente le prove di inclusione può essere noioso.

Forniamo un altro strumento automatizzato chiamato Uraniborg che può rilevare e misurare tutti i pacchetti attualmente installati sul tuo dispositivo. Il suo output viene inserito direttamente nello strumento verifier, consentendoti di scoprire e verificare la trasparenza di tutte le app sul tuo dispositivo in un unico passaggio.

Per utilizzare questo flusso di lavoro automatizzato, assicurati che il tuo dispositivo Android sia connesso al computer tramite ADB. Il codice sorgente di Uraniborg è incluso anche nel repository android-binary-transparency.

Esegui lo script automate_observation.py che si trova nella directory scripts/python:

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

Al termine dello script, dovresti vedere un output simile a questo:

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

Vai alla directory di output indicata dallo script. All'interno, individua il file denominato packages_with_inclusion_proof_signal.txt. Questo file elenca ogni pacchetto installato insieme a un campo inclusion_proof_verified impostato su true o false. Un valore true indica che il pacchetto è stato verificato crittograficamente rispetto al log di trasparenza, confermando che è conforme alle dichiarazioni del log.