Google si impegna a promuovere l'equità razziale per le comunità nere. Vedi come.
Questa pagina è stata tradotta dall'API Cloud Translation.
Switch to English

Schema di firma APK v2

APK Signature Scheme v2 è uno schema di firma a file intero che aumenta la velocità di verifica e rafforza le garanzie di integrità rilevando eventuali modifiche alle parti protette dell'APK.

La firma mediante APK Signature Scheme v2 inserisce un blocco di firma APK nel file APK immediatamente prima della sezione della directory centrale ZIP. All'interno del blocco di firma APK, le firme v2 e le informazioni sull'identità del firmatario sono archiviate in un blocco v2 dello schema di firma APK .

APK prima e dopo la firma

Figura 1. APK prima e dopo la firma

APK Signature Scheme v2 è stato introdotto in Android 7.0 (Nougat). Per rendere un APK installabile su dispositivi Android 6.0 (Marshmallow) e precedenti, l'APK deve essere firmato utilizzando la firma JAR prima di essere firmato con lo schema v2.

Blocco firma APK

Per mantenere la retrocompatibilità con il formato APK v1, le firme APK v2 e più recenti sono archiviate all'interno di un blocco di firma APK, un nuovo contenitore introdotto per supportare lo schema di firma APK v2. In un file APK, APK Signing Block si trova immediatamente prima della directory centrale ZIP, che si trova alla fine del file.

Il blocco contiene coppie ID-valore racchiuse in un modo che semplifica l'individuazione del blocco nell'APK. La firma v2 dell'APK viene archiviata come coppia ID-valore con ID 0x7109871a.

Formato

Il formato del blocco di firma APK è il seguente (tutti i campi numerici sono little-endian):

  • size of block in byte (escluso questo campo) (uint64)
  • Sequenza di coppie valore-ID con prefisso uint64:
    • ID (uint32)
    • value (lunghezza variabile: lunghezza della coppia - 4 byte)
  • size of block in byte, uguale al primo campo (uint64)
  • magic "APK Sig Block 42" (16 byte)

L'APK viene analizzato prima trovando l'inizio della directory centrale ZIP (trovando il record ZIP di fine directory centrale alla fine del file, quindi leggendo l'offset iniziale della directory centrale dal record). Il valore magic fornisce un modo rapido per stabilire che ciò che precede la directory centrale è probabilmente il blocco di firma APK. La size of block valore size of block indica quindi in modo efficiente l'inizio del blocco nel file.

Le coppie ID-valore con ID sconosciuti devono essere ignorate durante l'interpretazione del blocco.

Blocco dello schema di firma APK v2

L'APK è firmato da uno o più firmatari / identità, ognuno rappresentato da una chiave di firma. Queste informazioni vengono archiviate come blocco v2 dello schema di firma APK. Per ciascun firmatario, vengono archiviate le seguenti informazioni:

  • (algoritmo di firma, digest, firma) tuple. Il digest viene archiviato per separare la verifica della firma dal controllo di integrità del contenuto dell'APK.
  • Catena di certificati X.509 che rappresenta l'identità del firmatario.
  • Attributi aggiuntivi come coppie chiave-valore.

Per ciascun firmatario, l'APK viene verificato utilizzando una firma supportata dall'elenco fornito. Le firme con algoritmi di firma sconosciuti vengono ignorate. Spetta a ciascuna implementazione scegliere quale firma utilizzare quando si incontrano più firme supportate. Ciò consente l'introduzione di metodi di firma più forti in futuro in modo compatibile con le versioni precedenti. L'approccio suggerito è verificare la firma più forte.

Formato

Il blocco dello schema di firma APK v2 è memorizzato all'interno del blocco di firma APK con ID 0x7109871a .

Il formato del blocco v2 dello schema di firma APK è il seguente (tutti i valori numerici sono little-endian, tutti i campi con prefisso di lunghezza usano uint32 per lunghezza):

  • sequenza con prefisso di lunghezza del signer prefisso di lunghezza:
    • signed data prefisso di lunghezza:
      • sequenza con prefisso di lunghezza dei digests prefisso di lunghezza:
      • sequenza con prefisso di lunghezza dei certificates X.509:
        • certificate X.509 con prefisso di lunghezza (modulo DER ASN.1)
      • sequenza con prefisso di lunghezza degli additional attributes prefisso di lunghezza:
        • ID (uint32)
        • value (lunghezza variabile: lunghezza dell'attributo aggiuntivo - 4 byte)
    • sequenza con prefissi di lunghezza delle signatures prefisso di lunghezza:
      • signature algorithm ID (uint32)
      • signature prefisso di lunghezza sui signed data
    • public key prefisso di lunghezza (SubjectPublicKeyInfo, modulo DER ASN.1)

ID algoritmo della firma

  • 0x0101 — RSASSA-PSS con digest SHA2-256, SHA2-256 MGF1, 32 byte di sale, rimorchio: 0xbc
  • 0x0102 — RSASSA-PSS con digest SHA2-512, SHA2-512 MGF1, 64 byte di sale, rimorchio: 0xbc
  • 0x0103 — RSASSA-PKCS1-v1_5 con digest SHA2-256. Questo è per i sistemi di compilazione che richiedono firme deterministiche.
  • 0x0104 — RSASSA-PKCS1-v1_5 con digest SHA2-512. Questo è per i sistemi di compilazione che richiedono firme deterministiche.
  • 0x0201 — ECDSA con digest SHA2-256
  • 0x0202 — ECDSA con digest SHA2-512
  • 0x0301 — DSA con digest SHA2-256

Tutti gli algoritmi di firma sopra sono supportati dalla piattaforma Android. Gli strumenti di firma possono supportare un sottoinsieme degli algoritmi.

Dimensioni chiavi supportate e curve EC:

  • RSA: 1024, 2048, 4096, 8192, 16384
  • CE: NIST P-256, P-384, P-521
  • DSA: 1024, 2048, 3072

Contenuti protetti da integrità

Ai fini della protezione dei contenuti APK, un APK è composto da quattro sezioni:

  1. Contenuto delle voci ZIP (dall'offset 0 fino all'inizio del blocco di firma APK)
  2. Blocco firma APK
  3. ZIP Central Directory
  4. ZIP End of Central Directory

Sezioni APK dopo la firma

Figura 2. Sezioni APK dopo la firma

Schema di firma APK v2 protegge l'integrità delle sezioni 1, 3, 4 e i blocchi di signed data blocco Schema di firma APK v2 contenuti nella sezione 2.

L'integrità delle sezioni 1, 3 e 4 è protetta da uno o più digest dei loro contenuti archiviati in blocchi di signed data che, a loro volta, sono protetti da una o più firme.

Il digest sulle sezioni 1, 3 e 4 viene calcolato come segue, simile a un albero Merkle a due livelli. Ogni sezione è suddivisa in blocchi consecutivi da 1 MB (2 20 byte). L'ultimo pezzo in ciascuna sezione può essere più corto. Il digest di ogni blocco viene calcolato sulla concatenazione del byte 0xa5 , la lunghezza del blocco in byte (little-endian uint32) e il contenuto del blocco. Il digest di livello superiore viene calcolato sulla concatenazione del byte 0x5a , sul numero di blocchi (little-endian uint32) e sulla concatenazione dei digest dei blocchi nell'ordine in cui i blocchi compaiono nell'APK. Il digest viene calcolato in modo frammentato per consentire di accelerare il calcolo parallelizzandolo.

Digest APK

Figura 3. Dig APK

La protezione della sezione 4 (ZIP End of Central Directory) è complicata dalla sezione contenente l'offset di ZIP Central Directory. L'offset cambia quando cambia la dimensione del blocco di firma APK, ad esempio quando viene aggiunta una nuova firma. Pertanto, quando si calcola il digest sulla fine ZIP della directory centrale, il campo contenente l'offset della directory centrale ZIP deve essere trattato come contenente l'offset del blocco di firma APK.

Protezioni di rollback

Un utente malintenzionato potrebbe tentare di far verificare un APK con firma v2 come APK con firma v1 su piattaforme Android che supportano la verifica dell'APK con firma v2. Per mitigare questo attacco, gli APK con firma v2 che sono anche firmati v1 devono contenere un attributo X-Android-APK-Signed nella sezione principale dei loro file META-INF / *. SF. Il valore dell'attributo è un set separato da virgole di ID schema di firma APK (l'ID di questo schema è 2). Quando si verifica la firma v1, il verificatore APK è tenuto a rifiutare gli APK che non hanno una firma per lo schema di firma APK che il verificatore preferisce da questo set (ad esempio, schema v2). Questa protezione si basa sul fatto che i contenuti META-INF / *. I file SF sono protetti dalle firme v1. Vedere la sezione sulla verifica APK firmata JAR .

Un utente malintenzionato potrebbe tentare di eliminare firme più forti dal blocco v2 dello schema di firma APK. Per mitigare questo attacco, l'elenco degli ID dell'algoritmo di firma con cui l'APK veniva firmato viene archiviato nel blocco signed data che è protetto da ciascuna firma.

Verifica

In Android 7.0 e versioni successive, gli APK possono essere verificati in base allo schema di firma APK v2 + o alla firma JAR (schema v1). Le piattaforme precedenti ignorano le firme v2 e verificano solo le firme v1.

Processo di verifica della firma APK

Figura 4. Processo di verifica della firma APK (nuovi passaggi in rosso)

Verifica dell'APK Signature Scheme v2

  1. Individua il blocco firma APK e verifica che:
    1. Due campi di dimensioni di APK Signing Block contengono lo stesso valore.
    2. ZIP Central Directory è immediatamente seguito dal record ZIP End of Central Directory.
    3. ZIP End of Central Directory non è seguito da più dati.
  2. Individua il primo blocco v2 Schema firma APK all'interno del blocco firma APK. Se il blocco v2 se presente, procedere al passaggio 3. In caso contrario, tornare alla verifica dell'APK utilizzando lo schema v1 .
  3. Per ogni signer nel blocco Schema firma APK v2:
    1. Scegli l' signature algorithm ID supportato più forte dalle signatures . L'ordinamento della forza dipende da ogni versione di implementazione / piattaforma.
    2. Verificare la signature corrispondente dalle signatures rispetto ai signed data utilizzando public key . (Ora è sicuro analizzare i signed data .)
    3. Verificare che l'elenco ordinato di ID algoritmo di firma nei digests e nelle signatures sia identico. (Questo serve a prevenire lo stripping / aggiunta della firma.)
    4. Calcola il digest dei contenuti APK usando lo stesso algoritmo digest dell'algoritmo digest usato dall'algoritmo di firma.
    5. Verificare che il digest calcolato sia identico al digest corrispondente dai digests .
    6. Verificare che SubjectPublicKeyInfo del primo certificate di certificates sia identico alla public key .
  4. La verifica ha esito positivo se viene trovato almeno un signer e il passaggio 3 ha avuto signer positivo per ciascun signer trovato.

Nota : l'APK non deve essere verificato utilizzando lo schema v1 se si verifica un errore nel passaggio 3 o 4.

Verifica APK firmata JAR (schema v1)

L'APK con firma JAR è un JAR con firma standard , che deve contenere esattamente le voci elencate in META-INF / MANIFEST.MF e in cui tutte le voci devono essere firmate dallo stesso set di firmatari. La sua integrità è verificata come segue:

  1. Ogni firmatario è rappresentato da una voce JAR META-INF / <signer> .SF e META-INF / <signer>. (RSA | DSA | EC).
  2. <signer>. (RSA | DSA | EC) è un ContentInfo CMS PKCS # 7 con struttura SignedData la cui firma è verificata sul file <signer> .SF.
  3. <signer> .SF contiene un digest di file intero di META-INF / MANIFEST.MF e digest di ciascuna sezione di META-INF / MANIFEST.MF. Il digest dell'intero file di MANIFEST.MF è verificato. In caso contrario, viene verificato il digest di ciascuna sezione MANIFEST.MF.
  4. META-INF / MANIFEST.MF contiene, per ciascuna voce JAR protetta da integrità, una sezione con nome corrispondente contenente il digest del contenuto non compresso della voce. Tutti questi digest sono verificati.
  5. La verifica APK ha esito negativo se l'APK contiene voci JAR che non sono elencate in MANIFEST.MF e che non fanno parte della firma JAR.

La catena di protezione è quindi <signer>. (RSA | DSA | EC) -> <signer> .SF -> MANIFEST.MF -> contenuto di ciascuna voce JAR protetta da integrità.