Android 9 supporta la rotazione della chiave dell'APK, che consente alle app di modificare la chiave di firma nell'ambito di un aggiornamento dell'APK. Per rendere pratica la rotazione, gli APK devono indicare i livelli di affidabilità tra la nuova e la vecchia chiave di firma. Per supportare la rotazione delle chiavi, abbiamo aggiornato lo schema di firma dell'APK dalla versione 2 alla versione 3 per consentire l'utilizzo delle chiavi nuove e precedenti. La versione 3 aggiunge informazioni sulle versioni dell'SDK supportate e una struttura di prova della rotazione al blocco di firma dell'APK.
Blocco di firma dell'APK
Per mantenere la compatibilità con il formato APK v1, le firme APK v2 e v3 vengono memorizzate in un blocco di firma APK, situato immediatamente prima del directory centrale ZIP.
Il formato del blocco di firma dell'APK v3 è lo stesso della v2. La firma v3 dell'APK è memorizzata come coppia ID-valore con ID 0xf05368c0.
Blocco dello schema di firma dell'APK v3
Lo schema v3 è progettato per essere molto simile allo schema v2. Ha lo stesso formato generale e supporta gli stessi ID algoritmo di firma, le stesse dimensioni delle chiavi e le stesse curve EC.
Tuttavia, lo schema v3 aggiunge informazioni sulle versioni dell'SDK supportate e sulla struttura della prova di rotazione.
Formato
Il blocco dello schema di firma dell'APK v3 è archiviato all'interno del blocco di firma dell'APK nell'ID
0xf05368c0
.
Il formato del blocco dello schema di firma dell'APK v3 segue quello della versione 2:
- sequenza con prefisso di lunghezza di
signer
con prefisso di lunghezza:signed data
con prefisso di lunghezza:- sequenza con prefisso di lunghezza di
digests
con prefisso di lunghezza:signature algorithm ID
(4 byte)digest
(con prefisso di lunghezza)
- sequenza con prefisso di lunghezza di X.509
certificates
:- X.509 con prefisso di lunghezza
certificate
(formato ASN.1 DER)
- X.509 con prefisso di lunghezza
minSDK
(uint32): questo firmatario deve essere ignorato se la versione della piattaforma è inferiore a questo numero.maxSDK
(uint32): questo firmatario deve essere ignorato se la versione della piattaforma è superiore a questo numero.- sequenza con prefisso di lunghezza di
additional attributes
con prefisso di lunghezza:ID
(uint32)value
(lunghezza variabile: lunghezza dell'attributo aggiuntivo - 4 byte)ID - 0x3ba06f8c
value -
Struct proof-of-rotation
- sequenza con prefisso di lunghezza di
minSDK
(uint32) - duplicato del valore minSDK nella sezione dei dati firmati - utilizzato per saltare la verifica di questa firma se la piattaforma corrente non rientra nell'intervallo. Deve corrispondere al valore dei dati firmati.maxSDK
(uint32) - duplicato del valore maxSDK nella sezione dei dati firmati - utilizzato per saltare la verifica di questa firma se la piattaforma corrente non è nell'intervallo. Deve corrispondere al valore dei dati firmati.- sequenza con prefisso di lunghezza di
signatures
con prefisso di lunghezza:signature algorithm ID
(uint32)signature
con prefisso di lunghezza susigned data
- con prefisso di lunghezza
public key
(SubjectPublicKeyInfo, formato ASN.1 DER)
Strutture proof-of-rotation e self-trusted-old-certs
La struttura della prova della rotazione consente alle app di ruotare la propria firma senza essere bloccate su altre app con cui comunicano. Per farlo, le firme delle app contengono due nuovi dati:
- affermazione per terze parti che il certificato di firma dell'app può essere considerato attendibile se i suoi predecessori sono considerati attendibili
- le vecchie credenziali di firma dell'app che l'app stessa considera ancora attendibili
L'attributo proof-of-rotation nella sezione dei dati firmati è costituito da un elenco con un solo collegamento, in cui ogni nodo contiene un certificato di firma utilizzato per firmare le versioni precedenti dell'app. Questo attributo è destinato a contenere le strutture di dati concettuali proof-of-rotation e self-trusted-old-certs. L'elenco è ordinato per versione con il certificato di firma più antico corrispondente al nodo principale. La struttura di dati della prova della rotazione viene creata facendo in modo che il certificato in ogni nodo firme quello successivo nell'elenco e, di conseguenza, fornisca a ogni nuova chiave la prova che deve essere considerata attendibile quanto le chiavi precedenti.
La struttura di dati self-trusted-old-certs viene creata aggiungendo flag a ogni
nodo che ne indicano l'appartenenza e le proprietà nell'insieme. Ad esempio, potrebbe essere presente un flag che indica che il certificato di firma in un determinato nodo è attendibile per l'ottenimento delle autorizzazioni di firma di Android. Questo flag consente ad altre app
firmate dal certificato precedente di continuare a ricevere un'autorizzazione di firma
definita da un'app firmata con il nuovo certificato di firma. Poiché l'intero attributo proof-of-rotation risiede nella sezione dei dati firmati del campo v3signer
, è protetto dalla chiave utilizzata per firmare l'APK contenente.
Questo formato esclude più chiavi di firma e la convergenza di diversi certificati di firma ancestrali in uno (più nodi iniziali in un sink comune).
Formato
La prova di rotazione è memorizzata all'interno del blocco dello schema di firma dell'APK v3 con ID 0x3ba06f8c
. Il formato è il seguente:
- sequenza con prefisso di lunghezza di
levels
con prefisso di lunghezza:signed data
con prefisso di lunghezza (dall'apposito certificato, se esistente)- X.509 con prefisso di lunghezza
certificate
(formato ASN.1 DER) signature algorithm ID
(uint32) - algoritmo utilizzato dal certificato nel livello precedente
- X.509 con prefisso di lunghezza
flags
(uint32) - flag che indica se questo certificato deve o meno essere nella struttura self-trusted-old-certs e per quali operazioni.signature algorithm ID
(uint32): deve corrispondere a quello della sezione dei dati firmati nel livello successivo.- lunghezza con prefisso
signature
rispetto a quanto soprasigned data
Più certificati
Non sono supportati più firmatari e Google Play non pubblica app firmate con più certificati.
Verifica
In Android 9 e versioni successive, gli APK possono essere verificati in base allo schema di firma dell'APK v3, v2 o v1. Le piattaforme meno recenti ignorano le firme v3 e tentano di verificare le firme v2 e poi v1.
Figura 1. Procedura di verifica della firma dell'APK
Verifica dello schema di firma dell'APK v3
- Individua il blocco di firma dell'APK e verifica che:
- Due campi di dimensioni del blocco di firma dell'APK contengono lo stesso valore.
- Il Directory centrale ZIP è immediatamente seguito dal record Fine directory centrale ZIP.
- La fine del directory centrale ZIP non è seguita da altri dati.
- Individua il primo blocco dello schema di firma dell'APK v3 all'interno del blocco di firma dell'APK. Se il blocco v3 è presente, vai al passaggio 3. In caso contrario, torna alla verifica dell'APK utilizzando lo schema v2.
- Per ogni
signer
nel blocco dello schema di firma APK v3 con una versione minima e massima dell'SDK compresa nell'intervallo della piattaforma corrente:- Scegli il
signature algorithm ID
più potente supportato dasignatures
. L'ordine di importanza dipende da ogni implementazione/versione della piattaforma. - Verifica il
signature
corrispondente dasignatures
rispetto asigned data
utilizzandopublic key
. Ora è possibile analizzaresigned data
. - Verifica che le versioni minime e massime dell'SDK nei dati firmati corrispondano a quelle
specificate per
signer
. - Verifica che l'elenco ordinato degli ID degli algoritmi di firma in
digests
esignatures
sia identico. (Questo è per impedire la rimozione/l'aggiunta della firma). - Calcola il digest dei contenuti dell'APK utilizzando lo stesso algoritmo di digest utilizzato dall'algoritmo di firma.
- Verifica che il digest calcolato sia identico al corrispondente
digest
didigests
. - Verifica che SubjectPublicKeyInfo del primo
certificate
dicertificates
sia identico apublic key
. - Se l'attributo proof-of-rotation esiste per
signer
, verifica che la struttura sia valida e chesigner
sia l'ultimo certificato nell'elenco.
- Scegli il
- La verifica è riuscita se è stato trovato esattamente un
signer
nell'intervallo della piattaforma corrente e il passaggio 3 è andato a buon fine per quelsigner
.
Convalida
Per verificare che il tuo dispositivo supporti correttamente la versione 3, esegui i PkgInstallSignatureVerificationTest.java
test CTS incts/hostsidetests/appsecurity/src/android/appsecurity/cts/
.