Atributos

En esta página, se proporciona información sobre las funciones criptográficas de Android Keystore, tal como las 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 se puede acceder desde 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 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 cadena de claves que se remonta 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 las 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 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.

Además de la lista anterior, las implementaciones de KeyMint (anteriormente Keymaster) proporcionan un servicio más, pero que no se expone como una API: la generación de números aleatorios. Se usa de forma interna para generar claves, vectores de inicialización (IV), relleno aleatorio y otros elementos de protocolos seguros que requieren aleatoriedad.

Primitivas necesarias

Todas las implementaciones de KeyMint proporcionan lo siguiente:

  • RSA
    • Compatibilidad con claves de 2048, 3072 y 4096 bits
    • Compatibilidad con el exponente público F4 (2^16 + 1)
    • Modos de padding para la firma RSA:
      • RSASSA-PSS (PaddingMode::RSA_PSS)
      • RSASSA-PKCS1-v1_5 (PaddingMode::RSA_PKCS1_1_5_SIGN)
    • Modos de resumen para la firma de RSA:
      • SHA-256
    • Modos de relleno para la encriptación y desencriptación de RSA:
      • Sin relleno
      • RSAES-OAEP (PaddingMode::RSA_OAEP)
      • RSAES-PKCS1-v1_5 (PaddingMode::RSA_PKCS1_1_5_ENCRYPT)
  • ECDSA
    • Se admite la compatibilidad con claves de 224, 256, 384 y 521 bits, con las curvas NIST P-224, P-256, P-384 y P-521, respectivamente.
    • Modos de resumen para ECDSA:
      • Sin resumen (obsoleto, se quitará en el futuro)
      • SHA-256
  • AES
    • Se admiten claves de 128 y 256 bits
    • CBC, CTR, ECB y GCM. La implementación de GCM no permite el uso de etiquetas menores de 96 bits ni longitudes de nonce que no sean de 96 bits.
    • Los modos de padding PaddingMode::NONE y PaddingMode::PKCS7 son compatibles con los modos CBC y ECB. Sin relleno, la encriptación en modo CBC o ECB falla si la entrada no es un múltiplo del tamaño del bloque.
  • HMAC SHA-256, con cualquier tamaño de clave de hasta al menos 32 bytes.

Se recomienda usar SHA1 y los otros miembros de la familia SHA2 (SHA-224, SHA384 y SHA512) para las implementaciones de KeyMint. Keystore las proporciona en software si la implementación de KeyMint en hardware no las proporciona.

También se recomiendan algunas primitivas para la interoperabilidad con otros sistemas:

  • Tamaños de clave más pequeños para RSA
  • Exponentes públicos arbitrarios para RSA

Control de acceso a las llaves

Las claves basadas en hardware que nunca se pueden extraer del dispositivo no brindan mucha seguridad si un atacante puede usarlas a voluntad (aunque son más seguras que las claves que se pueden filtrar). 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 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. Si una etiqueta se puede repetir, se especifica en la interfaz de HAL de KeyMint. Cuando se crea una clave, el llamador especifica una lista de autorización. La implementación de KeyMint subyacente de Keystore modifica la lista para especificar información adicional, como si la clave tiene protección contra reversión, y devuelve una lista de autorización "final", codificada en el BLOB de clave devuelto. Cualquier intento de usar la clave para cualquier operación criptográfica fallará si se modifica la lista de autorización final.

En Keymaster 2 y versiones anteriores, el conjunto de etiquetas posibles se define en la enumeración keymaster_authorization_tag_t y se fija de forma permanente (aunque se puede extender). Los nombres tenían el prefijo KM_TAG. Los primeros cuatro bits de los IDs de etiquetas se usan para indicar el tipo.

Keymaster 3 cambió el prefijo KM_TAG a Tag::.

Los tipos posibles incluyen los siguientes:

ENUM: Los valores de muchas etiquetas se definen en enumeraciones. Por ejemplo, los valores posibles de TAG::PURPOSE se definen en la enumeración keymaster_purpose_t.

ENUM_REP: Es igual que ENUM, excepto que la etiqueta se puede repetir en una lista de autorización. La repetición indica varios valores autorizados. Por ejemplo, es probable que una clave de encriptación tenga KeyPurpose::ENCRYPT y KeyPurpose::DECRYPT.

Cuando KeyMint crea una clave, el llamador especifica una lista de autorización 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 objeto keyblob que se devuelve. La lista de autorización codificada está vinculada de forma criptográfica al objeto keyblob, de modo que cualquier intento de modificar la lista de autorización (incluido el orden) genera un objeto keyblob no válido que no se puede usar para operaciones criptográficas.

Aplicación de hardware frente a la de software

No todas las implementaciones de hardware seguro contienen las mismas funciones. Para admitir una variedad de enfoques, Keymaster distingue entre la aplicación del control de acceso del mundo 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 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 de las claves asimétricas: las características de la 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 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 tienen copia de seguridad en hardware, consulta Atestació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 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 definen 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 tanto para encriptar como para firmar permite que un atacante que puede convencer al sistema de que desencripte datos arbitrarios genere firmas.

Importación de claves

Keymaster admite la exportación de claves públicas únicamente en formato X.509 y 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 autorizaciones 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 del usuario, 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 debe hacerlo. Si no se incluye ninguna de estas etiquetas, pero sí 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 cualquier app a la que le otorgue 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 extienden después de un reinicio. Después de un reinicio, todas las autenticaciones se invalidan. El tiempo de espera se puede establecer en un valor grande para indicar que la autenticación se requiere una vez por inicio (2^32 segundos son aproximadamente 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).

Keystore, no KeyMint, aplica UNLOCKED_DEVICE_REQUIRED. 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 se vulnera Keystore mientras el dispositivo está bloqueado.

Toda la criptografía y la generación de números aleatorios que se describen en esta sección usan BoringSSL, excepto cuando se menciona explícitamente el uso de KeyMint. Todos los secretos se borran en cuanto ya no son necesarios.

Superllaves de UnlockedDeviceRequired

Para proteger criptográficamente 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 tal manera que solo se puedan recuperar si el dispositivo 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 a UNLOCKED_DEVICE_REQUIRED:

  • Es 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.
  • Es la superclave asimétrica de UnlockedDeviceRequired. Este es un par de claves P-521 de ECDH. Encripta las claves de UNLOCKED_DEVICE_REQUIRED que se importan o generan mientras el dispositivo está bloqueado para el usuario. Para obtener más detalles, 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 (de forma indirecta) por la contraseña sintética del usuario:

  1. El servidor del sistema deriva la contraseña del almacén de claves del usuario a partir de la contraseña sintética del usuario con una KDF de SP800-108.
  2. El servidor del sistema pasa la contraseña de Keystore del usuario a Keystore.
  3. El almacén de claves 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. El almacén de claves 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 desencriptar estas superclaves cuando se conoce la contraseña sintética del usuario, por ejemplo, cuando se ingresa el PIN, el patrón o la contraseña correctos del usuario.

Keystore 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 borra 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 borra 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 de 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 biometría de clase 3 ("sólida") y el PIN, el patrón o la contraseña habilitados, Keystore se encarga de que las superclaves se puedan recuperar con cualquiera de los datos biométricos de clase 3 inscritos por el usuario (generalmente, 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 en KeyMint como una clave vinculada a datos biométricos que requiere que la autenticación biométrica se haya realizado correctamente en los últimos 15 segundos y borra las copias de texto simple de todas estas claves.
  • Si el usuario tiene un dato biométrico de clase 1 ("comodidad"), un dato biométrico de clase 2 ("débil") o un agente de confianza de desbloqueo activo habilitado, 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 método alternativo 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 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 datos biométricos y, de ser así, intenta desencriptarla. Esto solo se realiza correctamente si el usuario se autenticó correctamente con un dato biométrico de clase 3 en los últimos 15 segundos, lo que KeyMint (no Keystore) aplica.

Almacenamiento de claves mientras el dispositivo está bloqueado

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

  • Encriptación (creación de una clave UNLOCKED_DEVICE_REQUIRED mientras el dispositivo está bloqueado):
    1. Keystore genera un nuevo par de claves ECDH efímeras P-521.
    2. Keystore genera un secreto compartido realizando un acuerdo de clave ECDH entre la clave privada de este par de claves efímeras y la mitad pública de la clave asimétrica superior 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. El almacén de claves 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. El almacén de claves 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 clave ECDH entre la mitad pública del par de claves efímeras y la mitad privada de la clave asimétrica superior 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. El almacén de claves desencripta la clave UNLOCKED_DEVICE_REQUIRED con la clave AES-256-GCM.
    5. Keystore vuelve a encriptar la clave UNLOCKED_DEVICE_REQUIRED con la superclave simétrica UnlockedDeviceRequired. Esto no afecta las propiedades de seguridad de la clave, pero permite acceder a ella más rápidamente más adelante.

Vinculación de clientes

La vinculación del cliente, es decir, 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 del cliente opcionales (Tag::APPLICATION_ID y Tag::APPLICATION_DATA, respectivamente). Keystore trata estos valores como BLOB opacos y solo garantiza que los mismos BLOB que se presentaron durante la generación o importación de la clave se presenten para cada uso y sean idénticos byte por byte. KeyMint no devuelve los datos de vinculación del cliente. El llamador debe conocerla para usar la clave.

Esta función no está disponible para las apps.

Vencimiento

El almacén de claves 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 Keymaster se niega a realizar operaciones con la 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, firma, etcétera, o para "usar" un texto cifrado, 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 descifrar o verificar mensajes.

Dado que el tiempo real lo proporciona el mundo no seguro, las etiquetas relacionadas con el vencimiento se encuentran en la lista aplicada por 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 el hardware seguro de KeyMint proporciona durante el inicio, preferentemente a través del cargador de arranque. Esta cadena de bits está vinculada de forma criptográfica a cada clave administrada por KeyMint.

La raíz de confianza consta 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 el uso de una imagen del sistema diferente o si se cambia el estado de bloqueo, no se podrá usar ninguna de las claves protegidas por KeyMint creadas por el sistema anterior, 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, ya que imposibilita que un sistema operativo instalado por un atacante use las claves de KeyMint.

Llaves independientes

Algunos hardware seguros de KeyMint pueden optar por almacenar el material de claves de forma interna y devolver identificadores en lugar de material de claves encriptado. También puede haber otros casos en los que no se puedan usar las llaves hasta que esté disponible algún otro componente del sistema del mundo seguro o no seguro. El HAL de KeyMint permite que el llamador solicite que una clave sea "independiente" a través de la etiqueta TAG::STANDALONE, lo que significa que no se requieren recursos más allá del BLOB y el sistema KeyMint en ejecución. Las etiquetas asociadas con una clave se pueden inspeccionar para ver si una clave es independiente. Actualmente, solo se definen dos valores:

  • KeyBlobUsageRequirements::STANDALONE
  • KeyBlobUsageRequirements::REQUIRES_FILE_SYSTEM

Esta función no está disponible para las apps.

Velocidad

Cuando se crea, la velocidad de uso máxima se puede especificar con TAG::MIN_SECONDS_BETWEEN_OPS. Las implementaciones de TrustZone se niegan a realizar operaciones criptográficas con esa clave si se realizó una operación menos de TAG::MIN_SECONDS_BETWEEN_OPS segundos antes.

El enfoque simple para implementar límites de velocidad es una tabla de IDs de clave y marcas de tiempo del último uso. Esta tabla tiene un tamaño limitado, pero admite al menos 16 entradas. En el caso de que la tabla esté llena y no se puedan actualizar ni descartar entradas, las implementaciones de hardware seguro "fallan de forma segura" y prefieren rechazar todas las operaciones de claves con límite de velocidad hasta que venza una de las entradas. Es aceptable que todas las entradas venzan tras el reinicio.

Las claves también se pueden limitar a n usos por inicio con TAG::MAX_USES_PER_BOOT. Esto también requiere una tabla de seguimiento, que admite al menos cuatro claves y también es a prueba de fallas. Ten en cuenta que las apps no pueden crear claves limitadas por inicio. Esta función no se expone a través de Keystore y está reservada para las operaciones del sistema.

Esta función no está disponible para las apps.

Reinicialización del generador de números aleatorios

Dado que el hardware seguro genera números aleatorios para el material de claves y los vectores de inicialización (IV), y dado que los generadores de números aleatorios de hardware podrían no ser siempre completamente confiables, el HAL de KeyMint proporciona una interfaz para permitir que el cliente proporcione entropía adicional, que se mezcla con los números aleatorios generados.

Utiliza un generador de números aleatorios de hardware como fuente principal de la semilla. Los datos de inicialización proporcionados a través de la API externa no pueden ser la única fuente de aleatoriedad utilizada para la generación de números. Además, la operación de combinación utilizada debe garantizar que el resultado aleatorio sea impredecible si alguna de las fuentes de semilla es impredecible.