Atributos

En esta página, se incluye información sobre las funciones criptográficas del Almacén de claves de Android, como las que 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 clave privada o secreta 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 claves encriptado
  • Certificación de claves: La creación de claves asimétricas genera un certificado que contiene la parte de la 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 una clave que se encadena 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)

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 las claves y se vinculan de forma permanente a la clave, lo que garantiza que la clave 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 de KeyMint subyacente debe generar números al azar para admitir la generación de claves y la creación de vectores de inicialización (IV) o de relleno aleatorios. Para respaldar esto, el sistema Android proporciona periódicamente entropía adicional a la implementación de KeyMint.

Control de acceso a 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 robar). Por lo tanto, es fundamental que Keystore aplique controles de acceso.

Los controles de acceso se definen como una "lista de autorización" de pares de etiqueta y 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. La posibilidad de repetir una etiqueta se especifica en la interfaz de HAL de KeyMint (antes Keymaster).

Los valores de etiqueta admitidos se definen en el archivo Tag.aidl, y cada uno se asocia 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 emisor especifica una lista de autorización para la clave. Keystore y KeyMint modifican esta lista para agregar restricciones adicionales, y la implementación de KeyMint subyacente codifica la lista de autorización final en el blob de claves que se muestra. La lista de autorizaciones codificada se vincula criptográficamente al blob de claves, de modo que cualquier intento de modificar la lista de autorizaciones (incluido el orden) genera un blob de claves no válido que no se puede usar para operaciones criptográficas.

Aplicación de medidas por incumplimiento de hardware frente a 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 seguro y no seguro, 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 el KeyCharacteristics con el nivel de seguridad adecuado, según lo que pueda aplicar. Esta información también se expone en los registros de certificación para claves asimétricas: las características de clave para SecurityLevel::TRUSTED_ENVIRONMENT o SecurityLevel::STRONGBOX aparecen en la lista hardwareEnforced, y las características para SecurityLevel::SOFTWARE o SecurityLevel::KEYSTORE aparecen en la lista softwareEnforced.

Por ejemplo, el entorno seguro no suele aplicar restricciones en 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, el almacén de claves de Android aplica autorizaciones como Tag::ORIGINATION_EXPIRE_DATETIME 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 que usan la clave asociada:

  • Tag::ALGORITHM
  • Tag::KEY_SIZE
  • Tag::BLOCK_MODE
  • Tag::PADDING
  • Tag::CALLER_NONCE
  • Tag::DIGEST
  • Tag::MGF_DIGEST

Las siguientes etiquetas son repetibles, 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.

Objetivo

Las claves tienen un conjunto de propósitos asociados, expresados como una o más entradas de autorización con la etiqueta Tag::PURPOSE, que define cómo se pueden usar. Los propósitos 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 lo siguiente:

  • Pares de claves asimétricas en formato PKCS#8 codificado en 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, se incluye Tag::ORIGIN en la lista de autorización de claves correspondiente. Por ejemplo, si se generó una clave en hardware seguro, se encuentra Tag::ORIGIN con el valor KeyOrigin::GENERATED en la lista hw_enforced de las características de la clave, mientras que una clave que se importó en hardware seguro tiene el valor KeyOrigin::IMPORTED.

Autenticación de usuarios

Las implementaciones seguras de KeyMint no implementan la autenticación de usuarios, sino que dependen de otras apps de confianza que sí lo hacen. Para conocer la interfaz que implementan estas apps, consulta la página de Gatekeeper.

Los requisitos de autenticación del usuario se especifican a través de 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 el usuario debe autenticarse y cuándo. Si no hay ninguna de estas etiquetas, pero sí está presente Tag::USER_SECURE_ID, se requiere autenticación para cada uso de la clave.

  • Tag::NO_AUTHENTICATION_REQUIRED indica que no se requiere autenticación del usuario, aunque el acceso a la clave sigue restringido a la app propietaria (y a las apps a las que otorga acceso).
  • Tag::AUTH_TIMEOUT es un valor numérico que especifica, en segundos, qué tan reciente debe ser la autenticación del usuario para autorizar el uso de la clave. Los tiempos de espera no se mantienen después de un reinicio; después de un reinicio, se invalidan todas las autenticaciones. El tiempo de espera se puede establecer en un valor grande para indicar que se requiere autenticación una vez por inicio (2^32 segundos son ~136 años; presumiblemente, los dispositivos Android se reinician con más frecuencia que eso).

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 conocer la semántica detallada, consulta KeyProtection.Builder#setUnlockedDeviceRequired(boolean).

UNLOCKED_DEVICE_REQUIRED se aplica con el almacén de claves, no con KeyMint. Sin embargo, en Android 12 y versiones posteriores, Keystore protege criptográficamente 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 Keystore se ve comprometido mientras el dispositivo está bloqueado.

Toda la criptografía y la generación de números al azar que se describen en esta sección usan BoringSSL, excepto cuando se menciona de forma explícita el uso de KeyMint. Todos los secretos se restablecen a cero en cuanto ya no se necesitan.

Superclaves de UnlockedDeviceRequired

Para proteger de forma criptográfica las claves de UNLOCKED_DEVICE_REQUIRED, Keystore las "superencripta" antes de almacenarlas en su base de datos. Cuando es posible, protege las claves de superencriptación (superclaves) mientras el dispositivo está bloqueado, de modo que solo se puedan recuperar si se desbloquea correctamente el dispositivo. (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 de UnlockedDeviceRequired. Esta es una clave AES‑256‑GCM. Encripta las claves de UNLOCKED_DEVICE_REQUIRED que se importan, generan o usan 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 de UNLOCKED_DEVICE_REQUIRED que se importan o generan mientras el dispositivo está bloqueado para el usuario. Para obtener más información, consulta Cómo almacenar claves mientras el dispositivo está bloqueado.

Generación y protección de las superclaves

Cuando se crea un usuario, Keystore genera las superclaves UnlockedDeviceRequired del usuario y las almacena en su base de datos, encriptadas (indirectamente) por la contraseña sintética del usuario:

  1. El servidor del sistema deriva la contraseña del almacén de claves del usuario de la contraseña sintética del usuario con una KDF SP800-108.
  2. El servidor del sistema pasa la contraseña del almacén de claves del usuario al almacén de claves.
  3. Keystore genera las superclaves del usuario.
  4. Para cada una de las superclaves del usuario, haz lo siguiente:
    1. El almacén de claves genera una sal aleatoria.
    2. Keystore deriva una clave AES‑256‑GCM de la contraseña de Keystore del usuario y la sal con HKDF‑SHA256.
    3. Keystore encripta la parte secreta de la superclave con esta clave AES‑256‑GCM.
    4. Keystore almacena la superclave encriptada y su sal en su base de datos. Si es una clave asimétrica, la mitad pública de la clave también se almacena sin encriptar.

Este procedimiento permite que estas superclaves se desencripten cuando se conoce la contraseña sintética del usuario, como cuando se ingresa el PIN, el patrón o la contraseña correctos del usuario.

El almacén de claves también almacena en caché estas superclaves en la memoria, lo que le permite operar con claves de 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 restablece 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 restablece a cero 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 equivalente.
  • Si el usuario solo tiene habilitados los datos biométricos de clase 3 ("seguros") y el PIN, el patrón o la contraseña, Keystore se encarga de que las superclaves se puedan recuperar con cualquiera de los datos biométricos de clase 3 registrados del usuario (por lo general, la huella dactilar), 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 restablece a cero las copias de texto simple de todas estas claves.
  • Si el usuario tiene habilitado un agente de confianza de desbloqueo activo, un dato biométrico de clase 1 ("comodidad") o un dato biométrico de clase 2 ("débil"), Keystore mantiene las superclaves almacenadas en caché en texto sin formato. En este caso, no se proporciona seguridad criptográfica para las claves de 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 se desbloquea el dispositivo 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, se 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 datos biométricos y, si es así, intenta desencriptarla. Esto solo se realiza correctamente si el usuario se autenticó con un dato biométrico de clase 3 en los últimos 15 segundos, lo que aplica KeyMint (no Keystore).

Cómo almacenar claves mientras el dispositivo está bloqueado

Keystore permite que los usuarios importen y generen claves UNLOCKED_DEVICE_REQUIRED mientras el dispositivo está bloqueado. Usa un esquema de encriptación híbrido para garantizar que solo se puedan desencriptar cuando el dispositivo se desbloquee más adelante:

  • Encriptación (importación o generación de una clave UNLOCKED_DEVICE_REQUIRED mientras el dispositivo está bloqueado):
    1. Keystore genera un nuevo par de claves ECDH P-521 efímeras.
    2. Keystore genera un secreto compartido realizando un acuerdo de claves ECDH entre la clave privada de este par de claves efímeras y la mitad pública de la superclave asimétrica UnlockedDeviceRequired.
    3. El almacén de claves genera una sal aleatoria.
    4. Keystore deriva una clave AES‑256‑GCM del secreto compartido y la sal con HKDF‑SHA256.
    5. Keystore encripta la clave UNLOCKED_DEVICE_REQUIRED con esta clave AES‑256‑GCM.
    6. Keystore almacena la clave UNLOCKED_DEVICE_REQUIRED encriptada, la sal y la mitad pública del par de claves efímeras en su base de datos.
  • Desencriptación (con la clave UNLOCKED_DEVICE_REQUIRED creada mientras el dispositivo está desbloqueado):
    1. Keystore carga la clave UNLOCKED_DEVICE_REQUIRED encriptada, la sal y la mitad pública del par de claves efímeras desde su base de datos.
    2. Keystore genera un secreto compartido realizando un acuerdo de claves ECDH entre la mitad pública del par de claves efímeras y la mitad privada de la superclave asimétrica UnlockedDeviceRequired. La clave privada está disponible porque el dispositivo está desbloqueado.
    3. Keystore deriva una clave AES‑256‑GCM del secreto compartido y la sal con HKDF‑SHA256. Esta clave AES‑256‑GCM es la misma que se derivó durante la encriptación.
    4. Keystore desencripta la clave UNLOCKED_DEVICE_REQUIRED con la clave AES‑256‑GCM.
    5. El almacén de claves vuelve a encriptar la clave UNLOCKED_DEVICE_REQUIRED con la superclave simétrica de UnlockedDeviceRequired. Esto no afecta las propiedades de seguridad de la clave, pero permite que se acceda a ella con mayor rapidez más adelante.

Esta función permite que las apps almacenen datos mientras el dispositivo está bloqueado, de modo que solo se puedan desencriptar cuando el dispositivo esté desbloqueado. Para ello, las apps deben seguir estos pasos:

  1. Genera una clave AES‑256‑GCM fuera de Keystore.
  2. Encriptar datos con la clave AES‑256‑GCM
  3. Importa la clave AES‑256‑GCM al almacén de claves con el conjunto de protección de claves setUnlockedDeviceRequired(true).
  4. Restablece a cero la copia original de la clave.

Para desencriptar los datos mientras el dispositivo está desbloqueado, usa la clave que se importó a Keystore.

Vinculación de clientes

La vinculación del cliente, la asociación de una clave con una app cliente en 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 BLOB opacos y solo garantiza que los mismos BLOB presentados durante la generación o importación de claves se presenten para cada uso y sean idénticos byte por byte. KeyMint no devuelve los datos de vinculación del cliente. El emisor debe conocerlo para usar la clave.

Esta función no se expone a las apps.

Vencimiento

Keystore admite la restricción del uso de claves por fecha. El inicio de la validez y el vencimiento de la clave se pueden asociar con una clave, y Keystore 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 "origen" y "uso" se basa en si la clave se usa para "originar" un nuevo texto cifrado, una firma, etcétera, 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 las etiquetas no están presentes, se supone que la clave en cuestión siempre se puede usar para desencriptar o verificar mensajes.

Debido a que el tiempo de reloj de pared lo proporciona el mundo no seguro, las etiquetas relacionadas con el vencimiento se encuentran en la lista de aplicación de 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 de forma criptográfica a cada clave administrada por 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 arranque 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 podrá usar, a menos que se restablezca la raíz de confianza anterior y se inicie un sistema firmado por esa clave. El objetivo es aumentar el valor de los controles de acceso a claves aplicados por software, de modo que un sistema operativo instalado por un atacante no pueda usar las claves de KeyMint.

Reinicialización 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 completamente confiables, la 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 la fuente de origen principal. Los datos de origen proporcionados a través de la API externa no pueden ser la única fuente de aleatoriedad que se use para generar números. Además, la operación de mezcla que se use debe garantizar que el resultado aleatorio sea impredecible si alguna de las fuentes de origen es impredecible.