Android tiene el concepto de autenticadores de usuarios que se usan para desbloquear el dispositivo y controlar el acceso a las claves criptográficas. Esto implica los siguientes componentes:
- Proveedor de servicios y almacenamiento de claves criptográficas. Android Keystore proporciona servicios criptográficos respaldados por hardware para apps. El sistema Android Keystore a nivel del framework está respaldado por el servicio del sistema
keystore2
. Esto, a su vez, se basa en una implementación subyacente de KeyMint (anteriormente Keymaster) específica del proveedor que garantiza que solo se pueda acceder al material de claves en un entorno seguro respaldado por hardware, como un entorno de ejecución confiable (TEE) o un elemento seguro (SE). - Autenticadores de usuarios. Certifica que la autenticación del usuario se realizó correctamente.
Android admite los siguientes componentes de autenticación:
- Guardián para la autenticación de PIN, patrón o contraseña en el TEE
- Weaver (opcional) para la autenticación de PIN, patrón o contraseña en un elemento seguro
- Huella dactilar para la autenticación con huella dactilar
- Otros métodos de autenticación biométrica Los dispositivos que se envían con Android 9 o versiones posteriores pueden usar
BiometricPrompt
como un único punto de integración para huellas dactilares y otros datos biométricos.
keystore2
mediante el uso de tokens de autenticación (AuthTokens) con copia de seguridad en hardware .
Cada uno de estos componentes es específico del proveedor, pero la implementación del proveedor debe satisfacer una especificación de interfaz de la capa de abstracción de hardware (HAL) y aprobar las pruebas del conjunto de pruebas de proveedores (VTS) correspondientes.
Por lo general, las implementaciones de proveedores también se dividen en dos partes, conectadas por un mecanismo de comunicación específico del proveedor :
- Un servicio de HAL se ejecuta como un proceso del sistema Android y recibe solicitudes de Binder del sistema Android.
- Una aplicación de confianza (TA) se ejecuta en el entorno seguro y realiza las operaciones seguras reales.
Inscripción
En el primer inicio del dispositivo después de un restablecimiento de la configuración de fábrica, todos los autenticadores están preparados para recibir inscripciones de credenciales del usuario. En un principio, un usuario debe inscribir un PIN, un patrón o una contraseña con Gatekeeper (o Weaver, si está disponible). Esta inscripción inicial crea un identificador seguro (SID) de usuario de 64 bits generado de forma aleatoria que sirve como identificador para el usuario y como token de vinculación para el material criptográfico del usuario. Este SID del usuario está vinculado criptográficamente a su contraseña. Las autenticaciones correctas en Gatekeeper generan AuthTokens que contienen el SID del usuario para esa contraseña.
Un usuario que quiera cambiar una credencial existente debe presentarla. Si se verifica correctamente una credencial existente, el SID del usuario asociado con la credencial existente se transfiere a la credencial nueva, lo que permite que el usuario siga accediendo a las claves después de cambiar una credencial.
En algunas situaciones, un administrador de dispositivos puede realizar una inscripción no confiable para inscribir una credencial nueva sin presentar una credencial existente. Esto permite que el usuario acceda al dispositivo, pero las claves creadas con el SID del usuario anterior se pierden de forma permanente.
Autenticación
En esta sección, se describe un flujo de autenticación típico, que implica interacciones entre varios componentes en Android y el entorno seguro. Ten en cuenta que todos los componentes seguros comparten una clave HMAC secreta (por inicio) que usan para autenticar los mensajes de los demás.
Después de que un usuario configura una credencial y se le asigna un SID de usuario, puede iniciar la autenticación, que comienza cuando el usuario proporciona un PIN, un patrón, una contraseña, una huella dactilar o algún otro dato biométrico seguro.
Figura 1: Flujo de autenticación
- Un usuario proporciona un método de autenticación y el servicio asociado realiza una solicitud al servicio de HAL.
- Para el PIN, el patrón o la contraseña,
LockSettingsService
hace una solicitud agatekeeperd
. - Los flujos de autenticación basados en biometría dependen de la versión de Android.
En dispositivos con Android 8.x y versiones anteriores,
FingerprintService
realiza una solicitud afingerprintd
. En dispositivos con Android 9 y versiones posteriores,BiometricPrompt
realiza una solicitud al daemon biométrico apropiado (por ejemplo,fingerprintd
para huellas dactilares ofaced
para rostro) con la claseBiometricManager
adecuada, comoFingerprintManager
oFaceManager
. Independientemente de la versión, la autenticación biométrica se realiza de forma asíncrona después de que se envía la solicitud.
- Para el PIN, el patrón o la contraseña,
- El servicio de HAL envía datos a su contraparte de TA, que genera un AuthToken:
- Para la autenticación de PIN, patrón o contraseña,
gatekeeperd
envía el hash de PIN, patrón o contraseña al TA de Gatekeeper en el TEE a través del servicio HAL de Gatekeeper. Si la autenticación en el TEE se realiza correctamente, el TA de Gatekeeper emite un AuthToken que contiene el SID del usuario correspondiente (firmado con la clave HMAC compartida). - Para la autenticación con huellas dactilares,
fingerprintd
escucha los eventos de huellas dactilares y envía los datos al TA de huellas dactilares en el TEE a través de la HAL de huellas dactilares. Si la autenticación en el TEE se realiza correctamente, el TA de huellas dactilares emite un AuthToken (firmado con la clave HMAC de AuthToken). - Para otras autenticaciones biométricas, el daemon correspondiente escucha el evento biométrico y lo envía al servicio y al TA de HAL biométricos adecuados.
- Para la autenticación de PIN, patrón o contraseña,
- El AuthToken firmado resultante se pasa al servicio del sistema
keystore2
a través de una interfaz de Binder. - El servicio
keystore2
adjunta los AuthTokens para solicitar a KeyMint (anteriormente Keymaster) que realice operaciones criptográficas. El servicio de HAL de KeyMint las pasa al TA de KeyMint, que las verifica con la clave HMAC compartida con el gatekeeper y los componentes de TEE biométricos compatibles. KeyMint confía en la marca de tiempo del token como la última hora de autenticación y decide si permite el uso de la clave según la marca de tiempo.
El flujo de autenticación no requiere una comunicación directa entre los TA en el entorno seguro: los AuthTokens fluyen del TA del autenticador al servicio keystore2
en Android, que a su vez los pasa al TA de KeyMint.
Esto también permite que el servicio keystore2
rechace rápidamente las solicitudes que están destinadas a fallar, ya que tiene conocimiento de los AuthTokens disponibles en el sistema, lo que ahorra un IPC potencialmente costoso en el TEE.
Formato de AuthToken
El formato de AuthToken se proporciona en la especificación de AIDL en HardwareAuthToken.aidl
.
Flujo de inicio del dispositivo
Cada vez que se inicia un dispositivo, se debe generar la clave HMAC de AuthToken y compartirla con todos los componentes del TEE (Gatekeeper, KeyMint/Keymaster y los TA de biometría compatibles). Para evitar ataques de repetición, la clave HMAC se debe generar de forma aleatoria cada vez que se reinicia el dispositivo.
Existen dos formas comunes en que los TA adquieren acceso a esta clave HMAC compartida:
- Acuerdo de secreto compartido: El servicio
keystore2
realiza un protocolo de acuerdo de claves de múltiples vías durante el inicio del dispositivo, lo que permite la derivación segura de la clave HMAC entre los TA que participan. Sin embargo, los TA participantes deben tener acceso a un secreto común previamente compartido. - Acceso directo: Los TA que residen en el mismo entorno seguro pueden usar un mecanismo interno de comunicación entre procesos (que depende de la plataforma) para compartir la clave HMAC.
En cualquier caso, la clave HMAC nunca debe estar disponible fuera del TEE.
El sistema operativo Trusty, que se ejecuta junto con Android, es un ejemplo de un TEE, pero se pueden usar otros TEE. Trusty usa un sistema IPC interno para comunicarse directamente entre KeyMint y Gatekeeper, o el TA biométrico adecuado. La clave HMAC se mantiene solo en KeyMint. Fingerprint y Gatekeeper solicitan la clave a KeyMint para cada uso y no conservan ni almacenan en caché el valor.