Android utilizza il concetto di chiavi di crittografia con autenticazione utente che richiede i seguenti componenti:
- Provider di servizi e archiviazione di chiavi di crittografia. Memorizza le chiavi di crittografia e fornisce routine di crittografia standard su queste chiavi. Android supporta un Keystore basato su hardware e Keymaster per i servizi crittografici, inclusa la crittografia basata su hardware per l'archiviazione delle chiavi che potrebbe includere un Trusted Execution Environment (TEE) o un Secure Element (SE), come Strongbox.
- Autenticatori utente. Attestare la presenza dell'utente e/o
l'autenticazione riuscita. Android supporta Gatekeeper per l'autenticazione con PIN/sequenza/password e Fingerprint per l'autenticazione con impronta. I dispositivi forniti con Android 9 e versioni successive possono utilizzare
BiometricPrompt
come un unico punto di integrazione per la lettura dell'impronta e altri dati biometrici. Questi componenti comunicano il loro stato di autenticazione con il servizio del magazzino chiavi tramite un canale autenticato. Anche il sistema Android Keystore a livello di framework è supportato dal servizio Keystore.
I componenti Gatekeeper, Fingerprint e Biometric funzionano con Keystore e altri componenti per supportare l'utilizzo di token di autenticazione (AuthToken) basati su hardware.
Registrazione
Al primo avvio del dispositivo dopo un ripristino dei dati di fabbrica, tutti gli autenticatori sono preparati a ricevere le registrazioni delle credenziali da parte dell'utente. Un utente deve inizialmente registrare un PIN/una sequenza/una password con Gatekeeper. Questa registrazione iniziale crea un ID di sicurezza utente (SID) a 64 bit generato in modo casuale che funge da identificatore per l'utente e da token di associazione per il materiale cryptographic dell'utente. Questo SID utente è legato in modo criptato alla password dell'utente. Le autenticazioni riuscite a Gatekeeper generano token Auth che contengono il SID utente per quella password.
Un utente che vuole modificare una credenziale deve presentare una credenziale esistente. Se una credenziale esistente viene verificata correttamente, l'SID utente associato alla credenziale esistente viene trasferito alla nuova credenziale, consentendo all'utente di continuare ad accedere alle chiavi dopo aver modificato una credenziale. Se un utente non presenta una credenziale esistente, la nuova credenziale viene registrata con un SID utente completamente casuale. L'utente può accedere al dispositivo, ma le chiavi create con l'SID utente precedente vengono perdute definitivamente. Questo è noto come registrazione non attendibile.
In circostanze normali, il framework Android non consente la registrazione non attendibile, pertanto la maggior parte degli utenti non vedrà mai questa funzionalità. Tuttavia, il verificarsi di questo problema può essere causato da reimpostazioni forzate della password da parte di un amministratore del dispositivo o di un malintenzionato.
Autenticazione
Dopo aver configurato una credenziale e aver ricevuto un SID utente, l'utente può avviare l'autenticazione, che inizia quando fornisce un PIN, una sequenza, una password o un'impronta. Tutti i componenti TEE condividono una chiave segreta che utilizzano per autenticare i messaggi reciproci.

- Un utente fornisce un metodo di autenticazione e il servizio associato invia una richiesta al daemon associato.
- Per PIN, sequenza o password,
LockSettingsService
invia una richiesta agatekeeperd
. - I flussi di autenticazione basati sulla biometria dipendono dalla versione di Android.
Sui dispositivi con Android 8.x e versioni precedenti,
FingerprintService
invia una richiesta afingerprintd
. Sui dispositivi con Android 9 e versioni successive,BiometricPrompt
invia una richiesta al daemon biometrico appropriato (ad esempiofingerprintd
per le impronte digitali ofaced
per il volto) utilizzando la classeBiometricManager
appropriata, ad esempioFingerprintManager
oFaceManager
. Indipendentemente dalla versione, l'autenticazione biometrica avviene in modo asincrono dopo l'invio della richiesta.
- Per PIN, sequenza o password,
- Il daemon invia i dati alla controparte, che genera un token Auth:
- Per l'autenticazione tramite PIN/sequenza/password,
gatekeeperd
invia l'hash del PIN, della sequenza o della password a Gatekeeper nel TEE. Se l'autenticazione nel TEE ha esito positivo, Gatekeeper nel TEE invia un AuthToken contenente l'SID utente corrispondente (firmato con la chiave HMAC di AuthToken) alla sua controparte nel sistema operativo Android. - Per l'autenticazione tramite impronta,
fingerprintd
ascolta gli eventi di impronta e invia i dati a Fingerprint nel TEE. Se l'autenticazione nel TEE ha esito positivo, l'impronta nel TEE invia un AuthToken (firmato con la chiave HMAC AuthToken) alla sua controparte nel sistema operativo Android. - Per altri tipi di autenticazione biometrica, il daemon biometrico appropriato monitora l'evento biometrico e lo invia al componente TEE biometrico appropriato.
- Per l'autenticazione tramite PIN/sequenza/password,
- Il daemon riceve un AuthToken firmato e lo passa al servizio di gestione delle chiavi tramite un'estensione dell'interfaccia Binder del servizio.
gatekeeperd
invia una notifica anche al servizio del keystore quando il dispositivo viene bloccato di nuovo e quando la password del dispositivo cambia. - Il servizio del keystore passa gli AuthToken a Keymaster e li verifica utilizzando la chiave condivisa con Gatekeeper e il componente TEE biometrico supportato. Keymaster considera attendibile il timestamp nel token come ultima data/ora di autenticazione e basa una decisione di rilascio della chiave (per consentire a un'app di utilizzare la chiave) sul timestamp.
Formato AuthToken
Per garantire la condivisione e la compatibilità dei token tra lingue e componenti, il formato AuthToken è descritto in hw_auth_token.h
.
Il formato è un semplice protocollo di serializzazione con campi di dimensioni fisse.
Campo | Digitazione | Obbligatorio | Descrizione |
---|---|---|---|
Versione AuthToken | 1 byte | Sì | Tag gruppo per tutti i campi riportati di seguito. |
La sfida | Numero intero non firmato a 64 bit | No | Un numero intero casuale per impedire gli attacchi di replay. In genere, l'ID di un'operazione di crittografia richiesta. Attualmente utilizzato dalle autorizzazioni per le impronte transactional. Se presente, AuthToken è valido solo per le operazioni di crittografia contenenti la stessa sfida. |
SID utente | Numero intero non firmato a 64 bit | Sì | Identificatore utente non ripetuto legato crittograficamente a tutte le chiavi associate all'autenticazione del dispositivo. Per maggiori dettagli, consulta Gatekeeper. |
ID authenticator (ASID) | Intero senza segno a 64 bit in ordine di rete | No | Identificatore utilizzato per l'associazione a un criterio di autenticazione specifico. Tutti gli autenticatori hanno un proprio valore ASID che possono modificare in base alle proprie esigenze. |
Tipo di autenticatore | Numero intero non firmato a 32 bit in ordine di rete | Sì |
|
Timestamp | Intero senza segno a 64 bit in ordine di rete | Sì | Tempo (in millisecondi) dall'avvio del sistema più recente. |
HMAC AuthToken (SHA-256) | Blob a 256 bit | Sì | MAC SHA-256 con chiave di tutti i campi, ad eccezione del campo HMAC. |
Procedura di avvio del dispositivo
A ogni avvio di un dispositivo, la chiave HMAC AuthToken deve essere generata e condivisa con tutti i componenti TEE (Gatekeeper, Keymaster e trustlet di autenticazione biometrica supportati). Pertanto, per una maggiore protezione contro gli attacchi di replay, la chiave HMAC deve essere generata in modo casuale ogni volta che il dispositivo si riavvia.
Il protocollo per la condivisione di questa chiave HMAC con tutti i componenti è una funzionalità di implementazione dipendente dalla piattaforma. La chiave non deve mai essere resa disponibile al di fuori del TEE. Se un sistema operativo TEE non dispone di un meccanismo di comunicazione interprocessuale (IPC) interno e deve trasferire i dati tramite il sistema operativo non attendibile, il trasferimento deve essere eseguito tramite un protocollo di scambio di chiavi sicuro.
Il sistema operativo Trusty, che viene eseguito accanto ad Android, è un esempio di TEE, ma è possibile utilizzare altri TEE. Trusty utilizza un sistema IPC interno per comunicare direttamente tra Keymaster e Gatekeeper o il trustlet biometrico appropriato. La chiave HMAC viene conservata solo in Keymaster; Fingerprint e Gatekeeper richiedono la chiave a Keymaster per ogni utilizzo e non la mantengono o la memorizzano nella cache.
Poiché alcuni TEE non dispongono di un'infrastruttura IPC, non avviene alcuna comunicazione tra gli applet nel TEE. Ciò consente inoltre al servizio del keystore di negare rapidamente le richieste destinate a non andare a buon fine, in quanto conosce la tabella di autenticazione nel sistema, evitando un IPC potenzialmente costoso nel TEE.