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 dichiarazioni riportate 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 composta da hash. Un nodo foglia contiene i dati e un nodo padre contiene l'hash dei relativi figli.

Due calcoli fondamentali verificano la proprietà di non manomissione 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 APK specifica. 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 della struttura (o che la struttura non sia stata manomessa). In questa guida ci concentriamo sulla procedura di calcolo della prova di inclusione, mentre ci affidiamo a 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 testimoni standardizzato. Questa integrazione fornirà checkpoint testimoniati, garantendo la coerenza del log.

Per verificare che le app Google sul tuo dispositivo siano conformi alle dichiarazioni riportate nel modello del richiedente, segui questi passaggi.

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 una 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 di prima parte può essere verificata rispetto a questo log.

Prerequisiti per la verifica

Prima di verificare un APK estratto, sul computer devono essere installati i seguenti strumenti:

Android Debug Bridge (ADB)

ADB è uno strumento che comunica con un dispositivo Android, disponibile sul sito web degli strumenti della piattaforma SDK Android .

AAPT2

AAPT2 (Android Asset Packaging Tool) è uno strumento di build utilizzato per compilare e creare pacchetti delle risorse di un'app Android. È disponibile come strumento autonomo negli strumenti di build SDK Android 26.0.2 e versioni successive.

Golang

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

Strumento di verifica della prova di inclusione

Pubblichiamo un modulo Go denominato verifier nel repository GitHub android-binary-transparency. Questo strumento esegue query sul log di trasparenza degli APK di prima parte di Google per verificare se un pacchetto è incluso.

Per utilizzare questo strumento, clona prima il repository sul computer locale:

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

Il codice sorgente dello strumento di verifica è disponibile nel repository android-binary-transparency.

Costruire 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 dispositivo per consentire le adb connessioni.

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 dispositivo sono installati un APK di base e diversi APK suddivisi 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 al computer utilizzando il seguente comando (tieni 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 esaminare il relativo manifest (AndroidManifest.xml).

Poiché il manifest all'interno di un APK è in formato binario, utilizza lo strumento aapt2(installato durante il prerequisiti passaggio) 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'
...

Ripeti questo passaggio per ottenere le informazioni pertinenti finché non hai tenuto conto di tutti gli APK suddivisi installati sul dispositivo.

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

Poi, 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 Contenuti dei log. Selezionando un hash dai risultati come esempio (devi verificare l'hash di ogni APK suddiviso), il payload di 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.

Verificare l'inclusione del pacchetto (prova di inclusione)

Dopo aver 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 questa directory dovrebbe essere presente un eseguibile denominato verifier. Esegui lo strumento 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

Lo strumento di verifica utilizza i contenuti del checkpoint e del log (dalla directory dei riquadri) per verificare se il payload dell'APK è presente nel log di trasparenza, confermando che è stato pubblicato da Google.

Il comando restituisce l'output a stderr:

  • OK. inclusion check success! se il pacchetto è incluso nel log.
  • FAILURE in caso contrario.

Verificare automaticamente tutti i pacchetti su 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 automatico chiamato Uraniborg in grado di rilevare e misurare tutti i pacchetti attualmente installati sul tuo dispositivo. L'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 automatico, assicurati che il 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 al seguente:

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.