En esta página, se proporciona información sobre las funciones de criptografía del Almacenamiento de claves de Android, como lo proporciona la implementación subyacente de KeyMint (o Keymaster).
Primitivas criptográficas
El almacén de claves proporciona las siguientes categorías de operaciones:
- Creación de claves, lo que genera material de claves privadas o secretas al que solo puede acceder el entorno seguro Los clientes pueden crear claves de las siguientes maneras:
- Generación de claves nuevas
- Importación de material de clave sin encriptar
- Importación de material de clave encriptada
- Certificación de claves: La creación de claves asimétricas genera un certificado que contiene la parte de clave pública del par de claves. De manera opcional, este certificado también contiene información sobre los metadatos de la clave y el estado del dispositivo, todo firmado por un encadenamiento de claves a una raíz de confianza.
- Operaciones criptográficas:
- Encriptación y desencriptación simétricas (AES, 3DES)
- Desencriptación asimétrica (RSA)
- Firma asimétrica (ECDSA, RSA)
- Firma y verificación simétricas (HMAC)
- Acuerdo de claves asimétricas (ECDH)
Ten en cuenta que Keystore y KeyMint no controlan las operaciones de claves públicas para claves asimétricas.
Los elementos del protocolo, como el propósito, el modo y el padding, así como las restricciones de control de acceso, se especifican cuando se generan o importan claves y se vinculan de forma permanente a la clave, lo que garantiza que no se pueda usar de ninguna otra manera.
Las primitivas y los modos que debe admitir la implementación de KeyMint se describen en la especificación de la interfaz de HAL de IKeyMintDevice
.
La implementación subyacente de KeyMint debe realizar la generación de números aleatorios para admitir la generación de claves y la creación de relleno aleatorio o vectores de inicialización (IV). Para admitir esto, el sistema Android proporciona en forma periódica entropía adicional a la implementación de KeyMint.
Control de acceso a las claves
Las claves basadas en hardware que nunca se pueden extraer del dispositivo no proporcionan mucha seguridad si un atacante puede usarlas a voluntad (aunque son más seguras que las claves que se pueden extraer). Por lo tanto, es fundamental que el almacén de claves aplique controles de acceso.
Los controles de acceso se definen como una "lista de autorización" de pares etiqueta-valor. Las etiquetas de autorización son números enteros de 32 bits y los valores son de varios tipos. Algunas etiquetas se pueden repetir para especificar varios valores. Se especifica si se puede repetir una etiqueta en la interfaz de HAL de KeyMint (anteriormente Keymaster).
Los valores de etiqueta admitidos se definen en el archivo Tag.aidl
y cada uno está asociado con un TagType
que indica el tipo del valor asociado (por ejemplo, número entero o bytes) y si se puede repetir para especificar varios valores admitidos.
Cuando KeyMint crea una clave, el llamador especifica una lista de autorizaciones para la clave. Keystore y KeyMint modifican esta lista para agregar restricciones adicionales, y la implementación subyacente de KeyMint codifica la lista de autorización final en el keyblob que se muestra. La lista de autorizaciones codificada está vinculada criptográficamente al keyblob, de modo que cualquier intento de modificar la lista de autorizaciones (incluido el orden) genere un keyblob no válido que no se pueda usar para operaciones criptográficas.
Aplicación forzosa de hardware en comparación con la de software
No todas las implementaciones de hardware seguro contienen las mismas funciones. Para admitir una variedad de enfoques, KeyMint distingue entre la aplicación de control de acceso segura y no segura, o la aplicación de hardware y software, respectivamente.
Esto se expone en la API de KeyMint con el campo securityLevel
del tipo KeyCharacteristics
. El hardware seguro es responsable de colocar las autorizaciones en KeyCharacteristics
con el nivel de seguridad adecuado, según lo que puede aplicar. Esta información también se expone en los registros de certificación de claves asimétricas: las características clave de SecurityLevel::TRUSTED_ENVIRONMENT
o SecurityLevel::STRONGBOX
aparecen en la lista hardwareEnforced
, y las características de SecurityLevel::SOFTWARE
o SecurityLevel::KEYSTORE
aparecen en la lista softwareEnforced
.
Por ejemplo, el entorno seguro no suele aplicar las restricciones sobre el intervalo de fecha y hora en el que se puede usar una clave, ya que no tiene acceso confiable a la información de fecha y hora. Como resultado, Keystore aplica autorizaciones como Tag::ORIGINATION_EXPIRE_DATETIME
en Android y tendría SecurityLevel::KEYSTORE
.
Para obtener más información sobre cómo determinar si las claves y sus autorizaciones están respaldadas por hardware, consulta Certificación de claves.
Autorizaciones de construcción de mensajes criptográficos
Las siguientes etiquetas se usan para definir las características criptográficas de las operaciones con la clave asociada:
Tag::ALGORITHM
Tag::KEY_SIZE
Tag::BLOCK_MODE
Tag::PADDING
Tag::CALLER_NONCE
Tag::DIGEST
Tag::MGF_DIGEST
Las siguientes etiquetas se pueden repetir, lo que significa que se pueden asociar varios valores con una sola clave:
Tag::BLOCK_MODE
Tag::PADDING
Tag::DIGEST
Tag::MGF_DIGEST
El valor que se usará se especifica en el momento de la operación.
Propósito
Las claves tienen un conjunto asociado de propósitos, expresados como una o más entradas de autorización con la etiqueta Tag::PURPOSE
, que define cómo se pueden usar. Los fines se definen en KeyPurpose.aidl
.
Ten en cuenta que algunas combinaciones de valores de propósito crean problemas de seguridad. Por ejemplo, una clave RSA que se puede usar para encriptar y firmar permite que un atacante que pueda convencer al sistema de desencriptar datos arbitrarios genere firmas.
Importación de claves
KeyMint admite la importación de los siguientes elementos:
- Pares de claves asimétricas en formato PKCS#8 con codificación DER (sin encriptación basada en contraseñas)
- Claves simétricas como bytes sin procesar
Para garantizar que las claves importadas se puedan distinguir de las claves generadas de forma segura, Tag::ORIGIN
se incluye en la lista de autorizaciones de claves adecuada. Por ejemplo, si una clave se generó en hardware seguro, Tag::ORIGIN
con el valor KeyOrigin::GENERATED
se encuentra en la lista hw_enforced
de las características clave, mientras que una clave que se importó a hardware seguro tiene el valor KeyOrigin::IMPORTED
.
Autenticación de usuarios
Las implementaciones seguras de KeyMint no implementan la autenticación del usuario, pero dependen de otras apps de confianza que sí lo hacen. Para ver la interfaz que implementan estas apps, consulta la página de Gatekeeper.
Los requisitos de autenticación del usuario se especifican mediante dos conjuntos de etiquetas. El primer conjunto indica qué métodos de autenticación permiten el uso de la clave:
Tag::USER_SECURE_ID
tiene un valor numérico de 64 bits que especifica el ID de usuario seguro que se proporciona en un token de autenticación seguro para desbloquear el uso de la clave. Si se repite, la clave se puede usar si alguno de los valores se proporciona en un token de autenticación seguro.
El segundo conjunto indica si se debe autenticar al usuario y cuándo.
Si no hay ninguna de estas etiquetas, pero sí Tag::USER_SECURE_ID
, se requiere la autenticación para cada uso de la clave.
Tag::NO_AUTHENTICATION_REQUIRED
indica que no se requiere la autenticación del usuario, aunque el acceso a la clave sigue restringido a la app propietaria (y a cualquier app a la que otorgue acceso).Tag::AUTH_TIMEOUT
es un valor numérico que especifica, en segundos, cuán reciente debe ser la autenticación del usuario para autorizar el uso de la clave. Los tiempos de espera no se transfieren entre reinicios. Después de un reinicio, se invalidan todas las autenticaciones. El tiempo de espera se puede establecer en un valor alto para indicar que se requiere la autenticación una vez por inicio (2^32 segundos son aproximadamente 136 años; se supone que los dispositivos Android se reinician con más frecuencia).
Cómo solicitar que se desbloquee el dispositivo
Las claves con Tag::UNLOCKED_DEVICE_REQUIRED
solo se pueden usar mientras el dispositivo está desbloqueado. Para obtener la semántica detallada, consulta
KeyProtection.Builder#setUnlockedDeviceRequired(boolean)
.
Keystore aplica UNLOCKED_DEVICE_REQUIRED
, no KeyMint. Sin embargo, en Android 12 y versiones posteriores, el almacén de claves protege de forma criptográfica las claves UNLOCKED_DEVICE_REQUIRED
mientras el dispositivo está bloqueado para garantizar que, en la mayoría de los casos, no se puedan usar, incluso si el almacén de claves está comprometido mientras el dispositivo está bloqueado.
Para lograrlo, el almacén de claves "superencripta" todas las claves UNLOCKED_DEVICE_REQUIRED
antes de almacenarlas en su base de datos y, cuando es posible, protege las claves de superencriptación (superclaves) mientras el dispositivo está bloqueado de manera tal que solo se puedan recuperar si se desbloquea correctamente. (Se usa el término "superencriptación" porque esta capa de encriptación se aplica además de la capa de encriptación que KeyMint ya aplica a todas las claves).
Cada usuario (incluidos los perfiles) tiene dos superclaves asociadas con UNLOCKED_DEVICE_REQUIRED
:
- La superclave simétrica UnlockedDeviceRequired. Esta es una clave AES-256-GCM. Encripta las claves
UNLOCKED_DEVICE_REQUIRED
que se importan o generan mientras el dispositivo está desbloqueado para el usuario. - La superclave asimétrica UnlockedDeviceRequired. Este es un par de claves ECDH P-521. Encripta las claves
UNLOCKED_DEVICE_REQUIRED
que se importan o generan mientras el dispositivo está bloqueado para el usuario. Las claves encriptadas con esta clave asimétrica se vuelven a encriptar con la clave simétrica en el primer uso (lo que solo puede ocurrir mientras el dispositivo está desbloqueado).
El almacén de claves genera estas superclaves en el momento de la creación del usuario y las almacena en su base de datos, encriptadas con la contraseña sintética del usuario. Esto permite que se recuperen con un PIN, un patrón o una contraseña equivalentes.
El almacén de claves también almacena en caché estas superclaves en la memoria, lo que le permite operar en claves UNLOCKED_DEVICE_REQUIRED
. Sin embargo, intenta almacenar en caché las partes secretas de estas claves solo mientras el dispositivo está desbloqueado para el usuario. Cuando el dispositivo está bloqueado para el usuario, Keystore pone a cero su copia almacenada en caché de las partes secretas de estas superclaves, si es posible. Específicamente, cuando el dispositivo está bloqueado para el usuario, Keystore selecciona y aplica uno de los tres niveles de protección para las superclaves UnlockedDeviceRequired del usuario:
- Si el usuario solo tiene habilitado el PIN, el patrón o la contraseña, Keystore anula las partes secretas de sus superclaves almacenadas en caché. Esto hace que las superclaves solo se puedan recuperar a través de la copia encriptada en la base de datos, que solo se puede desencriptar con un PIN, un patrón o una contraseña equivalentes.
- Si el usuario solo tiene datos biométricos de clase 3 (“fuertes”) y tiene habilitado el PIN, el patrón o la contraseña, Keystore organiza las superclaves para que cualquiera de los datos biométricos de clase 3 inscritos del usuario (por lo general, la huella dactilar) pueda recuperarlas, como alternativa al PIN, el patrón o la contraseña equivalentes. Para ello, genera una nueva clave AES-256-GCM, encripta las partes secretas de las superclaves con ella, importa la clave AES-256-GCM a KeyMint como una clave vinculada a la biometría que requiere que la autenticación biométrica se haya realizado correctamente en los últimos 15 segundos y pone a cero las copias de texto simple de todas estas claves.
- Si el usuario tiene habilitada una biométrica de clase 1 ("práctica"), de clase 2 ("débil") o un agente de confianza de desbloqueo activo, el almacén de claves mantiene las superclaves almacenadas en caché en texto simple. En este caso, no se proporciona seguridad criptográfica para las claves
UNLOCKED_DEVICE_REQUIRED
. Los usuarios pueden evitar este resguardo menos seguro si no habilitan estos métodos de desbloqueo. Los métodos de desbloqueo más comunes que se incluyen en estas categorías son el desbloqueo facial en muchos dispositivos y el desbloqueo con un reloj inteligente vinculado.
Cuando el dispositivo se desbloquea para el usuario, Keystore recupera las superclaves de UnlockedDeviceRequired del usuario si es posible. Para el desbloqueo equivalente con PIN, patrón o contraseña, desencripta la copia de estas claves que se almacena en la base de datos. De lo contrario, verifica si guardó una copia de estas claves encriptadas con una clave vinculada a la biometría y, de ser así, intenta desencriptarla. Esto tiene éxito solo si el usuario se autenticó correctamente con una biométrica de clase 3 en los últimos 15 segundos, que aplica KeyMint (no Keystore).
Vinculación de clientes
La vinculación de clientes, la asociación de una clave con una app de cliente particular, se realiza a través de un ID de cliente opcional y algunos datos de cliente opcionales (Tag::APPLICATION_ID
y Tag::APPLICATION_DATA
, respectivamente). Keystore trata estos valores como objetos blob opacos y solo se asegura de que los mismos objetos blob que se presentan durante la generación o importación de claves se presenten para cada uso y sean idénticos byte por byte. KeyMint no muestra los datos de vinculación del cliente. El llamador debe conocerla para usar la clave.
Esta función no está expuesta a las apps.
Vencimiento
El almacén de claves admite la restricción del uso de claves por fecha. El inicio de validez y el vencimiento de las claves se pueden asociar con una clave, y el almacén de claves se niega a realizar operaciones de clave si la fecha y hora actuales están fuera del rango válido. El rango de validez de la clave se especifica con las etiquetas Tag::ACTIVE_DATETIME
, Tag::ORIGINATION_EXPIRE_DATETIME
y Tag::USAGE_EXPIRE_DATETIME
. La distinción entre "origenación" y "uso" se basa en si la clave se usa para "originar" un texto cifrado, una firma, etcétera, nuevos, o para "usar" un texto cifrado, una firma, etcétera, existente. Ten en cuenta que esta distinción no se expone a las apps.
Las etiquetas Tag::ACTIVE_DATETIME
, Tag::ORIGINATION_EXPIRE_DATETIME
y Tag::USAGE_EXPIRE_DATETIME
son opcionales. Si no hay etiquetas, se supone que la clave en cuestión siempre se puede usar para desencriptar o verificar mensajes.
Debido a que el mundo no seguro proporciona la hora del reloj, las etiquetas relacionadas con el vencimiento se encuentran en la lista que aplica el software.
Vinculación de la raíz de confianza
El almacén de claves requiere que las claves estén vinculadas a una raíz de confianza, que es una cadena de bits que se proporciona al hardware seguro de KeyMint durante el inicio, preferiblemente por el bootloader. Esta cadena de bits está vinculada criptográficamente a cada clave que administra KeyMint.
La raíz de confianza consiste en el hash de la clave pública que se usa para verificar la firma en la imagen de inicio y el estado de bloqueo del dispositivo. Si se cambia la clave pública para permitir que se use una imagen del sistema diferente o si se cambia el estado de bloqueo, ninguna de las claves protegidas por KeyMint que creó el sistema anterior se puede usar, a menos que se restablezca la raíz de confianza anterior y se inicie un sistema firmado con esa clave. El objetivo es aumentar el valor de los controles de acceso a claves que aplica el software, ya que hace imposible que un sistema operativo instalado por un atacante use las claves de KeyMint.
Regeneración del valor inicial del generador de números aleatorios
Debido a que el hardware seguro genera números aleatorios para el material de claves y los vectores de inicialización (IV), y a que los generadores de números aleatorios de hardware no siempre son del todo confiables, el HAL de KeyMint proporciona una interfaz para permitir que Keystore proporcione entropía adicional, que se mezcla con los números aleatorios generados.
Usa un generador de números aleatorios de hardware como fuente de valor inicial principal. Los datos iniciales proporcionados a través de la API externa no pueden ser la única fuente de aleatoriedad que se usa para la generación de números. Además, la operación de combinación que se usa debe garantizar que el resultado aleatorio sea impredecible si alguna de las fuentes de origen es impredecible.