Questa pagina contiene informazioni sulle funzionalità di crittografia di Keystore in Android 6.0 e versioni successive.
Primitivi di crittografia
Keystore fornisce le seguenti categorie di operazioni:
- Generazione di chiavi
- Importazione ed esportazione di chiavi asimmetriche (senza wrapping delle chiavi)
- Importazione di chiavi simmetriche non elaborate (nessun wrapping delle chiavi)
- Crittografia e decrittografia asimmetriche con modalità di riempimento appropriate
- Firma e verifica asimmetriche con modalità di concatenazione e riempimento appropriati
- Crittografia e decrittografia simmetrica nelle modalità appropriate, inclusa una modalità AEAD
- Generazione e verifica di codici di autenticazione dei messaggi simmetrici
Gli elementi del protocollo, come scopo, modalità e padding, nonché i vincoli di controllo dell'accesso, vengono specificati quando le chiavi vengono generate o importate e sono permanentemente associati alla chiave, garantendo che non possa essere utilizzata in nessun altro modo.
Oltre all'elenco riportato sopra, le implementazioni di Keymaster forniscono un altro servizio, che però non è esposto come API: la generazione di numeri random. Viene utilizzato internamente per la generazione di chiavi, vettori di inizializzazione (IV), padding casuale e altri elementi di protocolli sicuri che richiedono casualità.
Primitive necessarie
Tutte le implementazioni di Keymaster forniscono:
- RSA
- Supporto di chiavi a 2048, 3072 e 4096 bit
- Supporto dell'esponente pubblico F4 (2^16+1)
- Modalità di riempimento per la firma RSA:
- RSASSA-PSS (
PaddingMode::RSA_PSS
) - RSASSA-PKCS1-v1_5 (
PaddingMode::RSA_PKCS1_1_5_SIGN
)
- RSASSA-PSS (
- Modalità di digest per la firma RSA:
- SHA-256
- Modalità di riempimento per la crittografia/decrittografia RSA:
- Senza imbottitura
- RSAES-OAEP (
PaddingMode::RSA_OAEP
) - RSAES-PKCS1-v1_5 (
PaddingMode::RSA_PKCS1_1_5_ENCRYPT
)
- ECDSA
- Sono supportate chiavi a 224, 256, 384 e 521 bit, utilizzando rispettivamente le curve NIST P-224, P-256, P-384 e P-521
- Modalità di sintesi per ECDSA:
- Nessun digest (deprecato, verrà rimosso in futuro)
- SHA-256
- AES
- Sono supportate chiavi a 128 e 256 bit
- CBC, CTR, ECB e GCM. L'implementazione GCM non consente l'utilizzo di tag inferiori a 96 bit o di lunghezze di nonce diverse da 96 bit.
- Le modalità di riempimento
PaddingMode::NONE
ePaddingMode::PKCS7
sono supportate per le modalità CBC ed ECB. Senza padding, la crittografia in modalità CBC o ECB non va a buon fine se l'input non è un multiplo della dimensione del blocco.
- HMAC SHA-256, con qualsiasi dimensione della chiave fino ad almeno 32 byte.
SHA1 e gli altri membri della famiglia SHA2 (SHA-224, SHA384 e SHA512) sono vivamente consigliati per le implementazioni di Keymaster. Il Keystore le fornisce in software se l'implementazione di Keymaster hardware non le fornisce.
Alcune primitive sono consigliate anche per l'interoperabilità con altri sistemi:
- Dimensioni delle chiavi più piccole per RSA
- Esponenti pubblici arbitrari per l'RSA
Controllo di accesso alle chiavi
Le chiavi basate su hardware che non possono mai essere estratte dal dispositivo non forniscono molta sicurezza se un malintenzionato può utilizzarle a piacimento (anche se sono più sicure delle chiavi che possono essere esfiltrate). Pertanto, è fondamentale che Keystore applichi i controlli di accesso.
I controlli di accesso sono definiti come un "elenco di autorizzazioni" di coppie di tag/valori. I tag di autorizzazione sono numeri interi a 32 bit e i valori sono di vari tipi. Alcuni tag possono essere ripetuti per specificare più valori. La possibilità di ripetere un tag è specificata nell'interfaccia HAL di KeyMint (in precedenza Keymaster). Quando viene creata una chiave, l'utente chiamante specifica un elenco di autorizzazioni. L'implementazione di Keymaster sottostante al Keystore modifica l'elenco per specificare alcune informazioni aggiuntive, ad esempio se la chiave dispone della protezione del rollback, e restituisce un elenco di autorizzazioni "finale", codificato nel blob della chiave restituito. Qualsiasi tentativo di utilizzare la chiave per qualsiasi operazione di crittografia non va a buon fine se l'elenco di autorizzazione finale viene modificato.
Per Keymaster 2 e versioni precedenti, l'insieme di tag possibili è definito nell'enumerazione keymaster_authorization_tag_t
ed è fissato definitivamente (anche se può essere esteso).
I nomi sono stati preceduti da KM_TAG
. I quattro bit iniziali degli ID tag vengono utilizzati per indicare il tipo.
Keymaster 3 ha modificato il prefisso KM_TAG
in
Tag::
.
I tipi possibili includono:
ENUM
: molti valori dei tag sono definiti nelle enumerazioni. Ad esempio, i valori possibili di TAG::PURPOSE
sono definiti nell'enum keymaster_purpose_t
.
ENUM_REP
: come ENUM
,
tranne che il tag può essere ripetuto in un elenco di autorizzazioni. La ripetizione indica più valori autorizzati. Ad esempio, una chiave di crittografia probabilmente ha KeyPurpose::ENCRYPT
e KeyPurpose::DECRYPT
.
UINT
: numeri interi non firmati a 32 bit. Esempio:
TAG::KEY_SIZE
UINT_REP
: come UINT
,
tranne che il tag può essere ripetuto in un elenco di autorizzazioni. La ripetizione indica più valori autorizzati.
ULONG
: numeri interi non firmati a 64 bit. Esempio:
TAG::RSA_PUBLIC_EXPONENT
ULONG_REP
: come ULONG
,
tranne che il tag può essere ripetuto in un elenco di autorizzazioni. La ripetizione indica più valori autorizzati.
DATE
: valori data/ora, espressi in millisecondi a partire dal 1° gennaio 1970.
Esempio: TAG::PRIVKEY_EXPIRE_DATETIME
BOOL
: true o false. Si presume che un tag di tipo
BOOL
sia "false" se non è presente e
"true" se è presente. Esempio: TAG::ROLLBACK_RESISTANT
BIGNUM
: numeri interi di lunghezza arbitraria, expressed as a byte array in big-endian order. Esempio:
TAG::RSA_PUBLIC_EXPONENT
BYTES
: una sequenza di byte. Esempio:
TAG::ROOT_OF_TRUST
Applicazione tramite hardware o software
Non tutte le implementazioni hardware sicure contengono le stesse funzionalità. Per supportare una serie di approcci, Keymaster distingue tra applicazione di controlli di accesso a livello di mondo sicuri e non sicuri o, rispettivamente, applicazione hardware e software.
Tutte le implementazioni:
- Imposta la corrispondenza esatta (non l'applicazione) di tutte le autorizzazioni. Gli elenchi di autorizzazioni nei blob delle chiavi corrispondono esattamente alle autorizzazioni riportate durante la generazione delle chiavi, incluso l'ordinamento. Eventuali mancate corrispondenze causano un messaggio di diagnostica degli errori.
- Dichiara le autorizzazioni di cui vengono applicati i valori semantici.
Il meccanismo dell'API per dichiarare le autorizzazioni applicate dall'hardware si trova nella struttura keymaster_key_characteristics_t
. Divide l'elenco di autorizzazioni in due sottoelenchi, hw_enforced
e
sw_enforced
. L'hardware sicuro è responsabile di inserire i valori appropriati in ogni campo, in base a ciò che può applicare.
Inoltre, Keystore implementa l'applicazione basata su software di tutte le autorizzazioni, indipendentemente dal fatto che siano applicate dall'hardware sicuro o meno.
Ad esempio, prendiamo in considerazione un'implementazione basata su TrustZone che non supporta la scadenza delle chiavi. Potrebbe comunque essere creata una chiave con una data di scadenza. L'elenco di autorizzazioni della chiave include il tagTAG::ORIGINATION_EXPIRE_DATETIME
con la data di scadenza. Una richiesta al Keystore per le caratteristiche della chiave trova questo tag nell'elenco sw_enforced
e l'hardware sicuro non applica il requisito di scadenza. Tuttavia, i tentativi di utilizzare la chiave dopo la scadenza vengono rifiutati da Keystore.
Se poi viene eseguito l'upgrade del dispositivo con hardware sicuro che supporta la scadenza, una richiesta di caratteristiche della chiave trova TAG::ORIGINATION_EXPIRE_DATETIME
nell'elenco hw_enforced
e i tentativi di utilizzare la chiave dopo la scadenza non vanno a buon fine anche se il keystore viene compromesso o aggirato.
Per ulteriori informazioni su come determinare se le chiavi sono basate su hardware, consulta Attestazione delle chiavi.
Autorizzazioni per la costruzione di messaggi criptati
I seguenti tag vengono utilizzati per definire le caratteristiche crittografiche delle operazioni che utilizzano la chiave associata: TAG::ALGORITHM
, TAG::KEY_SIZE
, TAG::BLOCK_MODE
, TAG::PADDING
, TAG::CALLER_NONCE
e TAG::DIGEST
.
TAG::PADDING
, TAG::DIGEST
e PaddingMode::BLOCK_MODE
sono ripetibili, il che significa che è possibile associare più valori a una singola chiave e il valore da utilizzare viene specificato al momento dell'operazione.
Finalità
Le chiavi hanno un insieme di finalità associate, espresse come una o più voci di autorizzazione con il tag TAG::PURPOSE
, che definisce come possono essere utilizzate. Le finalità sono:
KeyPurpose::ENCRYPT
KeyPurpose::DECRYPT
KeyPurpose::SIGN
KeyPurpose::VERIFY
Qualsiasi chiave può avere un sottoinsieme di questi scopi. Tieni presente che alcune combinazioni creano problemi di sicurezza. Ad esempio, una chiave RSA che può essere utilizzata sia per la crittografia sia per la firma consente a un malintenzionato che riesce a convincere il sistema a decriptare dati arbitrari di generare firme.
Importazione ed esportazione
Keymaster supporta l'esportazione solo di chiavi pubbliche in formato X.509 e l'importazione di:
- Coppie di chiavi pubbliche e private in formato PKCS#8 con codifica DER, senza crittografia basata su password
- Chiavi simmetriche come byte non elaborati
Per garantire che le chiavi importate possano essere distinte da quelle generate in modo sicuro, TAG::ORIGIN
è inclusa nell'elenco di autorizzazione delle chiavi appropriato. Ad esempio, se una chiave è stata generata in hardware sicuro, TAG::ORIGIN
con valore KeyOrigin::GENERATED
si trova nell'elenco hw_enforced
delle caratteristiche della chiave, mentre una chiave importata in hardware sicuro ha il valore KeyOrigin::IMPORTED
.
Autenticazione utente
Le implementazioni di Keymaster sicure non implementano l'autenticazione utente, ma dipendono da altre app attendibili che lo fanno. Per l'interfaccia implementata da queste app, consulta la pagina Gatekeeper.
I requisiti di autenticazione utente vengono specificati tramite due insiemi di tag. Il primo insieme indica quale utente può utilizzare la chiave:
TAG::ALL_USERS
indica che la chiave è utilizzabile da tutti gli utenti. Se presente,TAG::USER_ID
eTAG::USER_SECURE_ID
non sono presenti.TAG::USER_ID
ha un valore numerico che specifica l'ID dell'utente autorizzato. Tieni presente che si tratta dell'ID utente Android (per il multiutente), non dell'UID dell'app, e viene applicato solo da software non sicuri. Se presente,TAG::ALL_USERS
non è presente.TAG::USER_SECURE_ID
ha un valore numerico di 64 bit che specifica l'ID utente sicuro fornito in un token di autenticazione sicuro per sbloccare l'utilizzo della chiave. Se ripetuta, la chiave può essere utilizzata se uno dei valori viene fornito in un token di autenticazione sicuro.
Il secondo insieme indica se e quando l'utente deve essere autenticato.
Se non è presente nessuno di questi tag, ma è presente TAG::USER_SECURE_ID
,
l'autenticazione è obbligatoria per ogni utilizzo della chiave.
NO_AUTHENTICATION_REQUIRED
indica che non è richiesta l'autenticazione dell'utente, anche se la chiave può essere utilizzata solo dalle app in esecuzione come gli utenti specificati daTAG::USER_ID
.TAG::AUTH_TIMEOUT
è un valore numerico che specifica, in secondi, quanto deve essere recente l'autenticazione utente per autorizzare l'utilizzo della chiave. Questo vale solo per le operazioni con chiavi private/segrete. Le operazioni con chiave pubblica non richiedono l'autenticazione. I timeout non si applicano ai riavvii. Dopo un riavvio, tutte le chiavi non vengono mai autenticate. Il timeout può essere impostato su un valore elevato per indicare che l'autenticazione è richiesta una volta per ogni avvio (2^32 secondi corrispondono a circa 136 anni; presumibilmente i dispositivi Android vengono riavviati più spesso).
Richiedi un dispositivo sbloccato
Le chiavi con TAG::UNLOCKED_DEVICE_REQUIRED
sono utilizzabili solo quando il dispositivo è sbloccato. Per la semantica dettagliata, consulta
KeyProtection.Builder#setUnlockedDeviceRequired(boolean)
.
UNLOCKED_DEVICE_REQUIRED
viene applicato da Keystore, non da
Keymaster. Tuttavia, in Android 12 e versioni successive, Keystore protegge in modo criptato le chiavi UNLOCKED_DEVICE_REQUIRED
quando il dispositivo è bloccato per garantire che, nella maggior parte dei casi, non possano essere utilizzate anche se Keystore è compromesso quando il dispositivo è bloccato.
Per farlo, Keystore "supercripta" tutte le chiaviUNLOCKED_DEVICE_REQUIRED
prima di archiviarle nel proprio database e, se possibile, protegge le chiavi di supercrittografia (super chiavi) mentre il dispositivo è bloccato in modo che possano essere recuperate solo sbloccando il dispositivo. Il termine "supercrittografia" viene utilizzato perché questo livello di crittografia viene applicato oltre a quello applicato da Keymaster a tutte le chiavi.
Ogni utente (inclusi i profili)
ha due super chiavi associate a UNLOCKED_DEVICE_REQUIRED
:
- La superchiave simmetrica UnlockedDeviceRequired. Si tratta di una
chiave AES‑256‑GCM. Crittografa
le chiavi
UNLOCKED_DEVICE_REQUIRED
importate o generate mentre il dispositivo è sbloccato per l'utente. - La superchiave asimmetrica UnlockedDeviceRequired. Si tratta di una coppia di chiavi ECDH
P-521. Crittografa le chiavi
UNLOCKED_DEVICE_REQUIRED
importate o generate mentre il dispositivo è bloccato per l'utente. Le chiavi criptate con questa chiave asimmetrica vengono sottoposte nuovamente a crittografia con la chiave simmetrica al primo utilizzo (che può avvenire solo quando il dispositivo è sbloccato).
Keystore genera queste super chiavi al momento della creazione dell'utente e le memorizza nel suo database, criptate dalla password sintetica dell'utente. In questo modo possono essere recuperati utilizzando un PIN, una sequenza o una password equivalente.
Il Keystore memorizza nella cache anche queste super chiavi in memoria, il che gli consente di operare sulle chiavi UNLOCKED_DEVICE_REQUIRED
. Tuttavia, tenta di memorizzare nella cache le parti segrete di queste chiavi solo quando il dispositivo è sbloccato per l'utente. Quando il dispositivo è bloccato per l'utente, Keystore azzera la copia memorizzata nella cache delle parti segrete di queste super chiavi, se possibile. Nello specifico, quando il dispositivo è bloccato per l'utente, Keystore seleziona e applica uno dei tre livelli di protezione per le super chiavi UnlockedDeviceRequired dell'utente:
- Se l'utente ha attivato solo il PIN, la sequenza o la password, Keystore imposta su zero le parti segrete delle super chiavi memorizzate nella cache. In questo modo, le chiavi super sono recuperabili solo tramite la copia criptata nel database che può essere decriptata solo tramite PIN, sequenza o password equivalente.
- Se l'utente ha solo dati biometrici di 3a classe ("sicuri") e ha attivato PIN, sequenza o password, il Keystore organizza le super chiavi in modo che siano recuperabili da qualsiasi dato biometrico di 3a classe registrato dall'utente (in genere l'impronta), come alternativa a PIN, sequenza o password. Per farlo, genera una nuova chiave AES‑256‑GCM, cripta con essa le parti segrete delle super chiavi, importa la chiave AES‑256‑GCM in Keymaster come chiave legata alla biometria che richiede che l'autenticazione biometrica sia andata a buon fine negli ultimi 15 secondi e azzera le copie in testo non criptato di tutte queste chiavi.
- Se l'utente ha un dato biometrico di classe 1 ("di praticità"), di classe 2 ("debole") o un agente di attendibilità di sblocco attivo, Keystore conserva le super chiavi in cache in testo non cifrato. In questo caso, la sicurezza crittografica per le chiavi
UNLOCKED_DEVICE_REQUIRED
non è fornita. Gli utenti possono evitare questo metodo alternativo meno sicuro disattivando questi metodi di sblocco. I metodi di sblocco più comuni che rientrano in queste categorie sono lo sblocco con il volto su molti dispositivi e lo sblocco con uno smartwatch accoppiato.
Quando il dispositivo viene sbloccato per l'utente, Keystore recupera le super chiavi UnlockedDeviceRequired dell'utente, se possibile. Per lo sblocco tramite PIN, sequenza o password, decripta la copia di queste chiavi memorizzata nel database. In caso contrario, controlla se ha salvato una copia di queste chiavi criptate con una chiave associata alla biometria e, in questo caso, tenta di decriptarla. L'operazione riesce solo se l'utente si è autenticato correttamente con un dato biometrico di classe 3 negli ultimi 15 secondi, applicato da Keymaster (non Keystore).
Association client
Il binding del client, ovvero l'associazione di una chiave a una determinata app client, viene eseguito tramite un ID client facoltativo e alcuni dati client facoltativi (TAG::APPLICATION_ID
e TAG::APPLICATION_DATA
, rispettivamente). Il keystore tratta questi valori come blob opachi, garantendo solo che gli stessi blob presentati durante la generazione/l'importazione delle chiavi vengano presentati per ogni utilizzo e siano identici byte per byte. I dati di associazione del client non vengono restituiti da
Keymaster. Il chiamante deve conoscerla per poter utilizzare la chiave.
Questa funzionalità non è esposta alle app.
Scadenza
Il keystore supporta la limitazione dell'utilizzo delle chiavi in base alla data. La data/ora di inizio e di scadenza della chiave possono essere associate a una chiave e Keymaster si rifiuta di eseguire operazioni con la chiave se la data/ora corrente non rientra nell'intervallo valido. L'intervallo di validità della chiave viene specificato con i tag
TAG::ACTIVE_DATETIME
,
TAG::ORIGINATION_EXPIRE_DATETIME
e
TAG::USAGE_EXPIRE_DATETIME
. La distinzione tra "origine" e "utilizzo" si basa sull'utilizzo della chiave per"generare " una nuova crittografia/firma/ecc. o per"utilizzare" una crittografia/firma/ecc. esistente. Tieni presente che questa distinzione non è esposta alle app.
I tag TAG::ACTIVE_DATETIME
,
TAG::ORIGINATION_EXPIRE_DATETIME
,
e TAG::USAGE_EXPIRE_DATETIME
sono facoltativi. Se i tag
non sono presenti, si presume che la chiave in discussione possa essere sempre utilizzata per decriptare/verificare i messaggi.
Poiché l'ora del sistema è fornita dal mondo non sicuro, è improbabile che i tag relativi alla scadenza siano nell'elenco applicato dall'hardware. L'applicazione forzata della scadenza tramite hardware richiederebbe che il mondo sicuro ottenga in qualche modo data e ora attendibili, ad esempio tramite un protocollo di risposta alla sfida con un timeserver remoto attendibile.
Collegamento della radice di attendibilità
Il Keystore richiede che le chiavi siano associate a una radice di attendibilità, ovvero una stringa di bit fornita all'hardware sicuro Keymaster durante l'avvio, preferibilmente dal bootloader. Questa stringa di bit è legata in modo crittografico a ogni chiave gestita da Keymaster.
La radice di attendibilità è costituita dalla chiave pubblica utilizzata per verificare la firma sull'immagine di avvio e lo stato di blocco del dispositivo. Se la chiave pubblica viene modificata per consentire l'utilizzo di un'immagine di sistema diversa o se viene modificato lo stato della serratura, nessuna delle chiavi protette da Keymaster create dal sistema precedente è utilizzabile, a meno che non venga ripristinato il precedente root of trust e venga avviato un sistema firmato da quella chiave. L'obiettivo è aumentare il valore dei controlli dell'accesso alle chiavi applicati tramite software impedendo a un sistema operativo installato dall'attaccante di utilizzare le chiavi Keymaster.
Chiavi autonome
Alcuni hardware sicuri Keymaster possono scegliere di memorizzare il materiale della chiave internamente
e restituire handle anziché materiale della chiave criptato. In alternativa, potrebbero esserci altri
casi in cui le chiavi non possono essere utilizzate finché non è disponibile un altro componente del sistema mondiale
non sicuro o sicuro. L'HAL Keymaster consente all'utente che chiama di richiedere che una chiave sia "autonoma" tramite il tag TAG::STANDALONE
, il che significa che non sono richieste risorse diverse dal blob e dal sistema Keymaster in esecuzione. I tag associati a una chiave possono essere controllati per verificare se la chiave è autonoma. Al momento sono definiti solo due valori:
KeyBlobUsageRequirements::STANDALONE
KeyBlobUsageRequirements::REQUIRES_FILE_SYSTEM
Questa funzionalità non è esposta alle app.
Velocità
Al momento della creazione, la velocità di utilizzo massima può essere specificata con TAG::MIN_SECONDS_BETWEEN_OPS
.
Le implementazioni di TrustZone rifiutano di eseguire operazioni di crittografia con quella chiave se un'operazione è stata eseguita meno di TAG::MIN_SECONDS_BETWEEN_OPS
secondi prima.
L'approccio semplice per implementare i limiti di velocità è una tabella di ID chiave e timestamp dell'ultimo utilizzo. Questa tabella ha dimensioni limitate, ma può contenere almeno 16 voci. Se la tabella è piena e non è possibile aggiornare o eliminare le voci, le implementazioni hardware sicure "non vanno a buon fine", preferendo rifiutare tutte le operazioni con chiavi limitate in termini di velocità fino alla scadenza di una delle voci. È accettabile che tutte le voci scadano al riavvio.
Le chiavi possono anche essere limitate a n utilizzi per avvio conTAG::MAX_USES_PER_BOOT
. È inoltre necessaria una tabella di monitoraggio che accolga almeno quattro chiavi e che sia anche fail-safe. Tieni presente che
le app non possono creare chiavi limitate per ogni avvio. Questa funzionalità
non è esposta tramite Keystore ed è riservata alle operazioni di sistema.
Questa funzionalità non è esposta alle app.
Nuova generazione di seed per il generatore di numeri casuali
Poiché l'hardware sicuro genera numeri casuali per il materiale delle chiavi e per i vettori di inizializzazione (IV) e poiché i generatori di numeri casuali hardware potrebbero non essere sempre completamente attendibili, l'HAL Keymaster fornisce un'interfaccia per consentire al cliente di fornire entropia aggiuntiva, che viene aggiunta ai numeri casuali generati.
Utilizza un generatore di numeri casuali hardware come origine del seed principale. I dati iniziali forniti tramite l'API esterna non possono essere l'unica fonte di casualità utilizzata per la generazione di numeri. Inoltre, l'operazione di miscelazione utilizzata deve garantire che l'output casuale sia imprevedibile se una delle fonti di seed è imprevedibile.
Questa funzionalità non è esposta alle app, ma viene utilizzata dal framework, che fornisce regolarmente all'hardware sicuro ulteriore entropia, recuperata da un'istanza Java SecureRandom.