Questa pagina illustra vari metodi per assicurarti che l'APK installato sul tuo dispositivo Android corrisponda alla rivendicazione effettuata nel modello di autore della rivendicazione. Ciò comporta l'estrazione dell'APK in discussione dal dispositivo, il controllo dell'integrità del codice ed esecuzione di una prova di inclusione del log sull'artefatto estratto.
Procedura di verifica
Un log di trasparenza viene implementato con un albero Merkle costituito da hash. Un nodo foglia contiene dati e un nodo principale contiene l'hash dei suoi nodi secondari.
In sostanza, vengono eseguiti due calcoli sull'albero di Merkle per verificare la proprietà di rilevamento di manomissioni dei log di trasparenza: la prova di inclusione e la prova di coerenza. Il primo dimostra che il log include una voce corrispondente a una determinata versione dell'APK. La voce del log include un hash, che è il digest SHA256 del token di firma del codice sotto forma di token web JSON (JWT), che può essere ottenuto dagli APK corrispondenti. Quest'ultimo dimostra che quando vengono aggiunte nuove voci all'albero, il nuovo checkpoint è (crittograficamente) coerente con la versione precedente dell'albero.
Per verificare un APK coperto, esegui un test di prova di inclusione basato su un checkpoint osservato. Tieni presente che prevediamo di integrare questo log con una rete di testimoni pubblici utilizzando un protocollo di testimonianza standardizzato. In questo modo verrà fornito un checkpoint verificato, che garantisce la coerenza del log.
Se vuoi verificare che l'APK sul tuo dispositivo sia conforme alla rivendicazione fatta nel modello del richiedente, consulta la descrizione riportata di seguito.
Prova dell'inclusione
Un utente Android può verificare che un APK coperto sul proprio dispositivo sia nel log estraendolo innanzitutto e i relativi metadati pertinenti, quindi confrontando l'hash radice ricomputato con l'hash radice contenuto nel checkpoint pubblicato. Se corrispondono, l'utente Android può usufruire di alcune protezioni descritte nel modello di minaccia.
Come verificare l'inclusione di un APK nel log
Come descritto in precedenza, l'elenco degli APK attualmente coperti è disponibile nella pagina Panoramica.
Prerequisiti per la verifica
Prima di procedere per verificare che l'APK che hai appena estratto dal tuo dispositivo sia conforme alla nostra rivendicazione, dovrai installare i seguenti strumenti da un computer connesso alla rete.
Android Debug Bridge (ADB)
ADB
è uno strumento che comunica con un dispositivo Android, disponibile sul sito web Android SDK Platform Tools.
bundletool
bundletool
è uno strumento utilizzato per creare un Android App Bundle (AAB). Può essere utilizzato anche per convertire un AAB in APK che possono essere installati sui dispositivi.
Può essere scaricato da GitHub.
Androguard
Androguard è una raccolta di strumenti utilizzati per analizzare gli APK. Può essere scaricato e installato dal sito web di Androguard.
Verificatore della prova dell'inclusione
Si tratta di un modulo Go che abbiamo pubblicato in un repository Git all'interno di Android Open Source Project (AOSP) denominato avb
.
È in grado di eseguire query sul log di trasparenza degli APK dei servizi di sistema di Google
e di indicare se un pacchetto è incluso nel log.
Un esempio di come viene utilizzato è disponibile in una successiva
sezione.
Per scaricare questo strumento, devi prima clonare il repository avb
.
computer:~$ git clone https://android.googlesource.com/platform/external/avb
Il codice sorgente del verificatore è disponibile in tools/transparency/verify
nel repository avb
.
Creare un payload per la verifica
Per verificare che l'APK estratto dal dispositivo in base alle nostre affermazioni sia corretto, devi creare un payload dei log dalle informazioni ricavate dall'APK.
Prima di iniziare, assicurati che adb
possa essere utilizzato sul tuo dispositivo attivando il debug adb.
Quindi, individua la posizione in cui è installato l'APK sul tuo dispositivo. Ai fini di questa guida, utilizzeremo l'APK Android System Key Verifier (com.google.android.contactkeys) come esempio pratico.
computer:~$ adb shell pm list packages -f | grep contactkeys
package:/data/app/~~i5WYSO4PuAAv798-eHdM7A==/com.google.android.contactkeys-PQCKjnn7xDqjeVhcUDibBA==/base.apk=com.google.android.contactkeys
Se l'APK Android System Key Verifier è installato sul tuo dispositivo, il comando riportato sopra restituirà un percorso che indica dove è installato sul tuo dispositivo. In caso contrario, non vedrai alcun output.
Quindi, scarica l'APK dal tuo dispositivo Android sul computer su cui stai lavorando utilizzando questo comando (tieni presente che la posizione effettiva e il nome del file APK sul tuo dispositivo possono variare):
computer:~$ mkdir -p /tmp/testdir && cd /tmp/testdir
computer:/tmp/testdir$ adb pull /data/app/~~i5WYSO4PuAAv798-eHdM7A==/com.google.android.contactkeys-PQCKjnn7xDqjeVhcUDibBA==/base.apk ./contactkeys_candidate.apk
Per ottenere e quindi verificare il nome del pacchetto dell'APK che hai appena scaricato, devi prima decomprimere l'APK, in quanto si tratta di un tipo speciale di file ZIP.
computer:/tmp/testdir$ mkdir extracted && unzip contactkeys_candidate.apk -d extracted/
Questo passaggio estrae tutti i file che componevano l'APK. Il nome e la versione del pacchetto sono disponibili nel manifest dell'APK, che in genere si trova in un file denominato AndroidManifest.xml
.
Tuttavia, il file manifest ottenuto è in formato binario, non è quindi leggibile da un essere umano. Per convertire il file XML binario in un formato leggibile, utilizziamo lo strumento axml
della suite androguard
(come richiesto per l'installazione nella sezione Prerequisiti).
computer:/tmp/testdir$ androguard axml extracted/AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1413" android:versionName="1.48.688082145" android:compileSdkVersion="35" android:compileSdkVersionCodename="VanillaIceCream" android:requiredSplitTypes="" android:splitTypes="" package="com.google.android.contactkeys" platformBuildVersionCode="35" platformBuildVersionName="VanillaIceCream">
Dall'output riportato sopra, ora possiamo essere certi che il nome del pacchetto di questo APK è
com.google.android.contactkeys
e il numero di versione (versionCode) è 1413
.
Ora cercheremo la firma della trasparenza del codice all'interno dell'APK. Deve essere un file denominato code_transparency_signed.jwt
contenuto nella cartella META-INF
tra gli altri file estratti dall'APK.
computer:/tmp/testdir$ sha256sum extracted/META-INF/code_transparency_signed.jwt
1779a2aee029112c2c9bfc9390b9678f3e5f4595b39705e8528dd522e8042f11 code_transparency_signed.jwt
Con questa stringa hash, ora abbiamo tutte le informazioni necessarie per mettere insieme un payload del log in base al formato descritto nella sezione Contenuti dei log. In questo esempio, un payload del log corrispondente dovrebbe avere il seguente aspetto:
1779a2aee029112c2c9bfc9390b9678f3e5f4595b39705e8528dd522e8042f11
SHA256(Signed Code Transparency JWT)
com.google.android.contactkeys
1143
Tieni presente anche il carattere di nuova riga dopo la versione del pacchetto.
Puoi salvare i contenuti in un file, ad esempio payload.txt
. Ti tornerà utile più avanti quando eseguirai il test di prova di inclusione.
Verificare l'autenticità della firma del codice APK
Ora dobbiamo verificare l'autenticità del token di firma del codice integrato nell'APK. Per farlo, utilizziamo bundletool
e la chiave pubblica della coppia di chiavi utilizzata per la firma. Vengono
pubblicati all'interno di ogni sezione dei rispettivi
APK. Supponendo che tu abbia salvato il certificato della chiave pubblica
(ad es. per Android System Key Verifier)
in un file denominato signing_cert_pubkey.pem
,
segui la guida riportata di seguito per eseguire la verifica della firma del codice.
Innanzitutto, devi creare un'archivio ZIP e aggiungere l'APK candidato all'archivio.
computer:/tmp/testdir$ zip -u test.zip contactkeys_candidate.apk
zip warning: test.zip not found or empty
adding: contactkeys_candidate.apk (deflated 58%)
computer:/tmp/testdir$ file test.zip
test.zip: Zip archive data, at least v2.0 to extract, compression method=deflate
Ora siamo pronti a utilizzare il comando check-transparency
di bundletool
per verificare se la firma del codice incorporata nell'APK candidato corrisponde a quella pubblicata.
computer:/tmp/testdir$ java -jar BUNDLETOOL_INSTALL_PATH/bundletool-all-version.jar check-transparency \
--mode=apk \
--apk-zip=test.zip \
--transparency-key-certificate=signing_cert_pubkey.pem
APK signature is valid. SHA-256 fingerprint of the apk signing key certificate (must be compared with the developer's public key manually): D9 E1 73 5B 2A 39 51 27 3A 87 35 B7 66 9E F1 9E F5 3A F1 C1 27 5C BA 31 39 3C 18 40 8B 03 79 D0
Code transparency signature verified for the provided code transparency key certificate.
Code transparency verified: code related file contents match the code transparency file.
Assicurati che l'output del comando riportato sopra indichi che sia la firma di trasparenza del codice sia la trasparenza del codice sono verificate.
In caso contrario, ad esempio se visualizzi un output come
Code transparency verification failed because the provided public key
certificate does not match the transparency file
,
significa che l'integrità del codice dell'APK in questione potrebbe essere potenzialmente compromessa e che non devi considerare attendibile l'APK.
Ricorda di verificare che la verifica venga eseguita con il certificato della chiave pubblica corretto.
In caso contrario, se tutto il resto è a posto, significa che l'autenticità della firma del codice è stata verificata per l'APK che stai convalidando.
Verifica dell'inclusione del pacchetto (prova dell'inclusione)
Utilizzando il payload che hai creato in precedenza, ora puoi verificare se il pacchetto in questione è stato incluso nel log di trasparenza.
Uno strumento di verifica dell'inclusione è stato pubblicato nel avb
repository all'interno
dell'Android Open Source Project. Per eseguirlo:
computer:external/avb/tools/transparency/verify$ PAYLOAD_PATH=PATH_TO_PAYLOAD_DIR/payload.txt
computer:external/avb/tools/transparency/verify$ go build cmd/verifier/verifier.go
computer:external/avb/tools/transparency/verify$ ./verifier --payload_path=${PAYLOAD_PATH} --log_type=google_system_apk
Il verificatore utilizza il checkpoint corrispondente e i contenuti del log (che si trovano nella directory dei riquadri) per verificare che il payload dell'APK sia nel log della trasparenza, verificando che sia effettivamente pubblicato da Google.
L'output del comando viene scritto in stdout:
OK. inclusion check success!
se il codice del pacchetto è incluso nel log,FAILURE
se non lo è.