Cómo verificar la copia de seguridad en hardware de pares de claves con certificación de claves

La certificación de claves te brinda más confianza respecto del hecho de que las claves que usas en tu app se conservan en el almacén de claves guardado en hardware del dispositivo. En las siguientes secciones, se describe la manera de verificar las propiedades de las claves guardadas en hardware e interpretar el esquema de los datos de extensión del certificado.

Nota: Antes de verificar las propiedades de las claves guardadas en hardware de un dispositivo en un entorno de producción, debes asegurarte de que el dispositivo admita certificación de claves a nivel del hardware. Para ello, debes comprobar que la cadena de certificación contenga un certificado raíz firmado por la clave raíz de certificación de Google y que el elemento attestationSecurityLevel dentro de la estructura de datos de la descripción de la clave se configure a nivel de seguridad de TrustedEnvironment.

Además, es importante verificar las firmas en la cadena de certificados y comprobar que ninguna de las claves de esta se haya revocado. Para ello, debes revisar la Lista de estado de revocación de certificados. A menos que todas sean válidas y que la raíz sea la clave de raíz de Google mencionada anteriormente, no deberías confiar por completo en la certificación. Sin embargo, ten en cuenta que los dispositivos que contienen certificados revocados son igual de confiables que los dispositivos que solo admiten la certificación de software. Tener una certificación válida es un indicador muy positivo. No tener una es un indicador neutral, no negativo.

Recuperación y verificación de un par de claves guardado en hardware

Durante la certificación de claves, debes especificar el alias de un par de claves. La herramienta de certificación, como contraprestación, proporciona una cadena de certificados que puedes usar para verificar las propiedades de ese par de claves.

Si el dispositivo admite certificación de claves a nivel del hardware, el certificado raíz de esa cadena se firma con una clave raíz de certificación, que el fabricante del dispositivo incluye en el almacén de claves guardadas en hardware del dispositivo en la fábrica.

Nota: En dispositivos que cuentan con certificación de claves guardadas en hardware, Android 7.0 (nivel de API 24) o versiones posteriores y Servicios de Google Play, el certificado raíz se firma con la clave raíz de certificación de Google. Debes verificar que este certificado raíz sea el que aparece a continuación.

Para implementar la certificación de claves, realiza lo siguiente:

  1. Usa el método getCertificateChain() de un objeto KeyStore para obtener una referencia a la cadena de certificados X.509 asociada con el almacén de claves guardadas en hardware.
  2. Comprueba la validez de cada certificado usando el método checkValidity() de un objeto X509Certificate. Verifica también que el certificado raíz sea confiable.

    Precaución: Si bien puedes completar este proceso directamente en la app, es más seguro comprobar el estado de revocación de los certificados en otro servidor de confianza.

  3. En un servidor independiente en el que confíes, obtén una referencia a la biblioteca del analizador ASN.1 que sea la más adecuada para tu conjunto de herramientas. Usa el analizador para extraer los datos de extensión de la certificación que aparece dentro del primer elemento de la cadena de certificados.

    En el ejemplo de certificación de claves, se usa el analizador ASN.1 de Bouncy Castle para extraer los datos de extensión de la certificación. Puedes usar este ejemplo como referencia para crear tu propio analizador.

    Para obtener más información sobre el esquema de los datos de extensión, consulta Esquema de los datos de extensión de los certificados.

  4. Compara los datos de extensión que recuperaste del analizador ASN.1 con el conjunto de valores que esperas que contenga la clave guardada en hardware.

    Precaución: Si bien puedes completar este proceso directamente en la app, es más seguro comprobar los datos de extensión del certificado en otro servidor en el que confíes.

Certificados raíz

El nivel de confianza de la certificación depende del certificado raíz de la cadena. Los dispositivos Android que hayan pasado la prueba necesaria para tener el conjunto de apps de Google, incluido Google Play, y que se hayan lanzado con Android 7.0 (nivel de API 24) o versiones posteriores deberían usar las claves de certificación firmadas por el certificado raíz de hardware de Google. El certificado es el siguiente:

      -----BEGIN CERTIFICATE-----
      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
      -----END CERTIFICATE-----
    

Si el certificado raíz que aparece en la cadena de certificación que recibes es el que se nombra más arriba y no se revocó ninguno de los certificados de la cadena, debes saber lo siguiente:

  1. Tu clave se encuentra en un hardware que Google considera seguro.
  2. Tiene las propiedades que se describen en la certificación.

Si la cadena de certificación tiene otro certificado raíz, Google no realiza reclamaciones de seguridad sobre el hardware. Esto no significa que la clave no esté comprometida, solo significa que la certificación no prueba que la clave se encuentre en hardware seguro y que deberías ajustar las suposiciones de seguridad de manera correspondiente.

Si el certificado raíz no es el que aparece arriba, es posible que se deba a uno de los dos motivos siguientes:

  • Lo más probable es que el dispositivo se haya lanzado con una versión de Android anterior a 7.0 y que no admita la certificación de hardware. En este caso, Android tiene una implementación de software de certificación que produce el mismo tipo de certificado, pero que se firma con una clave codificada mediante el código fuente de Android. Como esta clave de firma no es secreta, un atacante que fingió proporcionar un hardware seguro pudo haber creado la certificación.
  • El otro motivo probable es que el dispositivo no sea un dispositivo con Google Play. En ese caso, el fabricante del dispositivo puede crear su propia raíz y hacer las reclamaciones que desee sobre el significado de la certificación. Consulta la documentación del fabricante del dispositivo. Ten en cuenta que, hasta el momento de la publicación de este documento, Google no conoce fabricantes que hayan hecho esto.

Lista de estado de revocación de certificados

Las claves de certificación pueden revocarse por varios motivos, entre los que se incluyen el mal manejo o la posible extracción por parte de un atacante. Por consiguiente, es esencial que se contraste el estado de cada certificado en una cadena de certificación con la lista de estado de revocación de certificados oficial. Google mantiene esta lista, que se publica en https://android.googleapis.com/attestation/status. Esta URL muestra un archivo JSON que contiene el estado de revocación de los certificados que no tienen un estado normal válido. El formato del archivo JSON cumple con la siguiente definición del esquema de JSON (borrador 07):

{
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "properties": {
        "entries": {
          "description" : "Each entry represents the status of an attestation key. The dictionary-key is the certificate serial number in lowercase hex.",
          "type": "object",
          "propertyNames": {
             "pattern": "^[a-f0-9]*$"
          },
          "additionalProperties": {
            "type": "object",
            "properties": {
              "status": {
                "description": "[REQUIRED] Current status of the key.",
                "type": "string",
                "enum": ["REVOKED", "SUSPENDED"]
              },
              "expires": {
                "description": "[OPTIONAL] UTC date when certificate expires in ISO8601 format (YYYY-MM-DD). Can be used to clear expired certificates from the status list.",
                "type": "string",
                "format": "date"
              },
              "reason": {
                "description": "[OPTIONAL] Reason for the current status.",
                "type": "string",
                "enum": ["UNSPECIFIED", "KEY_COMPROMISE", "CA_COMPROMISE", "SUPERSEDED", "SOFTWARE_FLAW"]
              },
              "comment": {
                "description": "[OPTIONAL] Free form comment about the key status.",
                "type": "string",
                "maxLength": 140
              }
            },
            "required": ["status"],
            "additionalProperties": false
          }
        }
      },
      "required": ["entries"],
      "additionalProperties": false
    }

Ejemplo de lista de estado de revocación de certificados:

{
      "entries": {
        "2c8cdddfd5e03bfc": {
          "status": "REVOKED",
          "expires": "2020-11-13",
          "reason": "KEY_COMPROMISE",
          "comment": "Key stored on unsecure system"
        },
        "c8966fcb2fbb0d7a": {
          "status": "SUSPENDED",
          "reason": "SOFTWARE_FLAW",
          "comment": "Bug in keystore causes this key malfunction b/555555"
        }
      }
    }
    

CRL heredadas

Las URL de CRL incorporadas en certificaciones heredadas seguirán operando. Las nuevas certificaciones ya no incluirán una extensión de URL de CRL. También se incluirá el estado de los certificados heredados en la lista de estados de certificaciones, de modo que los desarrolladores puedan empezar a usar de manera segura la lista de estados de certificaciones tanto para los certificados nuevos como heredados. En el ejemplo de certificación de claves, se incluye un ejemplo de cómo verificar correctamente las claves de certificación de Android.

Esquema de los datos de extensión de los certificados

La certificación de claves verifica los datos de extensión que aparecen en el primer certificado de la cadena en un almacén de claves guardadas en hardware de un dispositivo. El certificado almacena información según un esquema de ASN.1. Para ver el esquema correspondiente a la versión de certificación que usas, selecciona la pestaña adecuada en el siguiente listado de esquemas:

Versión 3

    KeyDescription ::= SEQUENCE {
        attestationVersion  3,
        attestationSecurityLevel  SecurityLevel,
        keymasterVersion  INTEGER,
        keymasterSecurityLevel  SecurityLevel,
        attestationChallenge  OCTET_STRING,
        uniqueId  OCTET_STRING,
        softwareEnforced  AuthorizationList,
        teeEnforced  AuthorizationList,
    }

    SecurityLevel ::= ENUMERATED {
        Software  (0),
        TrustedEnvironment  (1),
        StrongBox  (2),
    }

    AuthorizationList ::= SEQUENCE {
        purpose  [1] EXPLICIT SET OF INTEGER OPTIONAL,
        algorithm  [2] EXPLICIT INTEGER OPTIONAL,
        keySize  [3] EXPLICIT INTEGER OPTIONAL,
        digest  [5] EXPLICIT SET OF INTEGER OPTIONAL,
        padding  [6] EXPLICIT SET OF INTEGER OPTIONAL,
        ecCurve  [10] EXPLICIT INTEGER OPTIONAL,
        rsaPublicExponent  [200] EXPLICIT INTEGER OPTIONAL,
        rollbackResistance  [303] EXPLICIT NULL OPTIONAL,
        activeDateTime  [400] EXPLICIT INTEGER OPTIONAL,
        originationExpireDateTime  [401] EXPLICIT INTEGER OPTIONAL,
        usageExpireDateTime  [402] EXPLICIT INTEGER OPTIONAL,
        noAuthRequired  [503] EXPLICIT NULL OPTIONAL,
        userAuthType  [504] EXPLICIT INTEGER OPTIONAL,
        authTimeout  [505] EXPLICIT INTEGER OPTIONAL,
        allowWhileOnBody  [506] EXPLICIT NULL OPTIONAL,
        trustedUserPresenceRequired  [507] EXPLICIT NULL OPTIONAL,
        trustedConfirmationRequired  [508] EXPLICIT NULL OPTIONAL,
        unlockedDeviceRequired  [509] EXPLICIT NULL OPTIONAL,
        allApplications  [600] EXPLICIT NULL OPTIONAL,
        applicationId  [601] EXPLICIT OCTET_STRING OPTIONAL,
        creationDateTime  [701] EXPLICIT INTEGER OPTIONAL,
        origin  [702] EXPLICIT INTEGER OPTIONAL,
        rootOfTrust  [704] EXPLICIT RootOfTrust OPTIONAL,
        osVersion  [705] EXPLICIT INTEGER OPTIONAL,
        osPatchLevel  [706] EXPLICIT INTEGER OPTIONAL,
        attestationApplicationId  [709] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdBrand  [710] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdDevice  [711] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdProduct  [712] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdSerial  [713] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdImei  [714] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdMeid  [715] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdManufacturer  [716] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdModel  [717] EXPLICIT OCTET_STRING OPTIONAL,
        vendorPatchLevel  [718] EXPLICIT INTEGER OPTIONAL,
        bootPatchLevel  [719] EXPLICIT INTEGER OPTIONAL,
    }

    RootOfTrust ::= SEQUENCE {
        verifiedBootKey  OCTET_STRING,
        deviceLocked  BOOLEAN,
        verifiedBootState  VerifiedBootState,
        verifiedBootHash OCTET_STRING,
    }

    VerifiedBootState ::= ENUMERATED {
        Verified  (0),
        SelfSigned  (1),
        Unverified  (2),
        Failed  (3),
    }
    

Versión 2

    KeyDescription ::= SEQUENCE {
        attestationVersion  2,
        attestationSecurityLevel  SecurityLevel,
        keymasterVersion  INTEGER,
        keymasterSecurityLevel  SecurityLevel,
        attestationChallenge  OCTET_STRING,
        uniqueId  OCTET_STRING,
        softwareEnforced  AuthorizationList,
        teeEnforced  AuthorizationList,
    }

    SecurityLevel ::= ENUMERATED {
        Software  (0),
        TrustedEnvironment  (1),
    }

    AuthorizationList ::= SEQUENCE {
        purpose  [1] EXPLICIT SET OF INTEGER OPTIONAL,
        algorithm  [2] EXPLICIT INTEGER OPTIONAL,
        keySize  [3] EXPLICIT INTEGER OPTIONAL,
        digest  [5] EXPLICIT SET OF INTEGER OPTIONAL,
        padding  [6] EXPLICIT SET OF INTEGER OPTIONAL,
        ecCurve  [10] EXPLICIT INTEGER OPTIONAL,
        rsaPublicExponent  [200] EXPLICIT INTEGER OPTIONAL,
        activeDateTime  [400] EXPLICIT INTEGER OPTIONAL,
        originationExpireDateTime  [401] EXPLICIT INTEGER OPTIONAL,
        usageExpireDateTime  [402] EXPLICIT INTEGER OPTIONAL,
        noAuthRequired  [503] EXPLICIT NULL OPTIONAL,
        userAuthType  [504] EXPLICIT INTEGER OPTIONAL,
        authTimeout  [505] EXPLICIT INTEGER OPTIONAL,
        allowWhileOnBody  [506] EXPLICIT NULL OPTIONAL,
        allApplications  [600] EXPLICIT NULL OPTIONAL,
        applicationId  [601] EXPLICIT OCTET_STRING OPTIONAL,
        creationDateTime  [701] EXPLICIT INTEGER OPTIONAL,
        origin  [702] EXPLICIT INTEGER OPTIONAL,
        rollbackResistant  [703] EXPLICIT NULL OPTIONAL,
        rootOfTrust  [704] EXPLICIT RootOfTrust OPTIONAL,
        osVersion  [705] EXPLICIT INTEGER OPTIONAL,
        osPatchLevel  [706] EXPLICIT INTEGER OPTIONAL,
        attestationApplicationId  [709] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdBrand  [710] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdDevice  [711] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdProduct  [712] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdSerial  [713] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdImei  [714] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdMeid  [715] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdManufacturer  [716] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdModel  [717] EXPLICIT OCTET_STRING OPTIONAL,
    }

    RootOfTrust ::= SEQUENCE {
        verifiedBootKey  OCTET_STRING,
        deviceLocked  BOOLEAN,
        verifiedBootState  VerifiedBootState,
    }

    VerifiedBootState ::= ENUMERATED {
        Verified  (0),
        SelfSigned  (1),
        Unverified  (2),
        Failed  (3),
    }
    

Versión 1

    KeyDescription ::= SEQUENCE {
        attestationVersion  1,
        attestationSecurityLevel  SecurityLevel,
        keymasterVersion  INTEGER,
        keymasterSecurityLevel  SecurityLevel,
        attestationChallenge  OCTET_STRING,
        uniqueId  OCTET_STRING,
        softwareEnforced  AuthorizationList,
        teeEnforced  AuthorizationList,
    }

    SecurityLevel ::= ENUMERATED {
        Software  (0),
        TrustedEnvironment  (1),
    }

    AuthorizationList ::= SEQUENCE {
        purpose  [1] EXPLICIT SET OF INTEGER OPTIONAL,
        algorithm  [2] EXPLICIT INTEGER OPTIONAL,
        keySize  [3] EXPLICIT INTEGER OPTIONAL,
        digest  [5] EXPLICIT SET OF INTEGER OPTIONAL,
        padding  [6] EXPLICIT SET OF INTEGER OPTIONAL,
        ecCurve  [10] EXPLICIT INTEGER OPTIONAL,
        rsaPublicExponent  [200] EXPLICIT INTEGER OPTIONAL,
        activeDateTime  [400] EXPLICIT INTEGER OPTIONAL,
        originationExpireDateTime  [401] EXPLICIT INTEGER OPTIONAL,
        usageExpireDateTime  [402] EXPLICIT INTEGER OPTIONAL,
        noAuthRequired  [503] EXPLICIT NULL OPTIONAL,
        userAuthType  [504] EXPLICIT INTEGER OPTIONAL,
        authTimeout  [505] EXPLICIT INTEGER OPTIONAL,
        allowWhileOnBody  [506] EXPLICIT NULL OPTIONAL,
        allApplications  [600] EXPLICIT NULL OPTIONAL,
        applicationId  [601] EXPLICIT OCTET_STRING OPTIONAL,
        creationDateTime  [701] EXPLICIT INTEGER OPTIONAL,
        origin  [702] EXPLICIT INTEGER OPTIONAL,
        rollbackResistant  [703] EXPLICIT NULL OPTIONAL,
        rootOfTrust  [704] EXPLICIT RootOfTrust OPTIONAL,
        osVersion  [705] EXPLICIT INTEGER OPTIONAL,
        osPatchLevel  [706] EXPLICIT INTEGER OPTIONAL,
    }

    RootOfTrust ::= SEQUENCE {
        verifiedBootKey  OCTET_STRING,
        deviceLocked  BOOLEAN,
        verifiedBootState  VerifiedBootState,
    }

    VerifiedBootState ::= ENUMERATED {
        Verified  (0),
        SelfSigned  (1),
        Unverified  (2),
        Failed  (3),
    }
    

En la lista siguiente se proporciona una descripción de cada elemento del esquema:

KeyDescription

Esta secuencia de valores ofrece información general sobre el par de claves que se verifica mediante la certificación de claves, y proporciona acceso sencillo a detalles adicionales.

attestationVersion
Versión de la función de certificación de claves.
attestationSecurityLevel

Nivel de seguridad de la certificación.

Advertencia: Si bien es posible certificar claves almacenadas en el sistema Android (es decir, si el valor de attestationSecurityLevel se configura en Software), no puedes confiar en esas certificaciones si el sistema Android se ve comprometido.

keymasterVersion
Versión de la capa de abstracción de hardware (HAL) de Keymaster. Usa 0 para representar la versión 0.2 o 0.3, 1 para representar la versión 1.0 y 2 para representar la versión 2.0.
keymasterSecurityLevel
Nivel de seguridad de la implementación de Keymaster.
uniqueId
Este valor identifica el dispositivo, pero solo por un período de tiempo limitado. Solo las apps del sistema lo computan y lo utilizan. En las demás apps, uniqueId está vacío.
softwareEnforced
Opcional. Es la lista de autorización de Keymaster que aplica el sistema Android, no el TEE del dispositivo.
teeEnforced
Opcional. Es la lista de autorización de Keymaster que aplica el TEE del dispositivo.

SecurityLevel

Esta estructura de datos indica el nivel de protección de una función de software, como un par de claves, en función de su ubicación en el dispositivo.

Dado que la estructura de datos es una enumeración, adquiere exactamente uno de los siguientes valores:

Software
La lógica para crear y controlar la función se implementa en el sistema Android. Para la creación y el almacenamiento de pares de claves, esta ubicación es menos segura que el TEE, pero es más segura que el espacio de procesos de tu app.
TrustedEnvironment
La lógica para crear y controlar la función se implementa en hardware seguro, como un TEE. Para la creación y el almacenamiento de pares de claves, esta ubicación es más segura porque el hardware seguro es muy resistente a los peligros remotos.
StrongBox
La lógica para crear y administrar una función se implementa en un módulo de seguridad de hardware dedicado. Para la creación y el almacenamiento de pares de claves, esta ubicación es más segura porque el hardware seguro es muy resistente a los peligros remotos y ataques de hardware contra el módulo.

AuthorizationList

Esta estructura de datos contiene las propiedades del par de claves, como se define en la capa de abstracción de hardware (HAL) de Keymaster. Debes comparar estos valores con el estado actual del dispositivo o con un conjunto de valores previstos para verificar que un par de claves siga siendo válido para usarse en tu app.

Cada nombre de campo corresponde a una etiqueta de Keymaster con una denominación similar. Por ejemplo, el campo keySize en una lista de autorizaciones corresponde a la etiqueta de autorización Tag::KEY_SIZE de Keymaster.

Cada uno de los campos de la siguiente lista es opcional:

purpose
Corresponde a la etiqueta de autorización Tag::PURPOSE de Keymaster, que usa un valor de ID de etiqueta de 1.
algorithm

Corresponde a la etiqueta de autorización Tag::ALGORITHM de Keymaster, que usa un valor de ID de etiqueta de 2.

En un objeto AuthorizationList de certificación, el valor del algoritmo es siempre RSA o EC.

keySize
Corresponde a la etiqueta de autorización Tag::KEY_SIZE de Keymaster, que usa un valor de ID de etiqueta de 3.
digest
Corresponde a la etiqueta de autorización Tag::DIGEST de Keymaster, que usa un valor de ID de etiqueta de 5.
padding
Corresponde a la etiqueta de autorización Tag::PADDING de Keymaster, que usa un valor de ID de etiqueta de 6.
ecCurve

Corresponde a la etiqueta de autorización Tag::EC_CURVE de Keymaster, que usa un valor de ID de etiqueta de 10.

Es el conjunto de parámetros empleados para generar un par de claves de curva elíptica (CE), que usa ECDSA para la firma y verificación, en el almacén de claves del sistema Android.

rsaPublicExponent
Corresponde a la etiqueta de autorización Tag::RSA_PUBLIC_EXPONENT de Keymaster, que usa un valor de ID de etiqueta de 200.
rollbackResistance

Solo está presente en la versión de certificación 3.

Corresponde a la etiqueta de autorización Tag::ROLLBACK_RESISTANT de Keymaster, que usa un valor de ID de etiqueta de 303.

activeDateTime
Corresponde a la etiqueta de autorización Tag::ACTIVE_DATETIME de Keymaster, que usa un valor de ID de etiqueta de 400.
originationExpireDateTime
Corresponde a la etiqueta de autorización Tag::ORIGINATION_EXPIRE_DATETIME de Keymaster, que usa un valor de ID de etiqueta de 401.
usageExpireDateTime
Corresponde a la etiqueta de autorización Tag::USAGE_EXPIRE_DATETIME de Keymaster, que usa un valor de ID de etiqueta de 402.
noAuthRequired

Corresponde a la etiqueta de autorización Tag::NO_AUTH_REQUIRED de Keymaster, que usa un valor de ID de etiqueta de 503.

userAuthType
Corresponde a la etiqueta de autorización Tag::USER_AUTH_TYPE de Keymaster, que usa un valor de ID de etiqueta de 504.
authTimeout
Corresponde a la etiqueta de autorización Tag::AUTH_TIMEOUT de Keymaster, que usa un valor de ID de etiqueta de 505.
allowWhileOnBody

Corresponde a la etiqueta de autorización Tag::ALLOW_WHILE_ON_BODY de Keymaster, que usa un valor de ID de etiqueta de 506.

Permite usar la clave después de su período de espera para la autenticación si el usuario todavía lleva el dispositivo consigo. Recuerda que un sensor corporal seguro determina si el dispositivo está en contacto con el cuerpo del usuario.

trustedUserPresenceRequired

Solo está presente en la versión de certificación 3.

Corresponde a la etiqueta de autorización Tag::TRUSTED_USER_PRESENCE_REQUIRED de Keymaster, que usa un valor de ID de etiqueta de 507.

Especifica que esta clave solo se puede usar si el usuario proporcionó una prueba de presencia física. Entre los ejemplos, se incluyen los siguientes:

  • Para una clave StrongBox, es un botón de hardware conectado con un pin en el dispositivo StrongBox.
  • Para una clave TEE, la autenticación de huella digital proporciona una prueba de presencia siempre y cuando el TEE tenga control exclusivo del escáner y realice el proceso de coincidencia de huella digital.
trustedConfirmationRequired

Solo está presente en la versión de certificación 3.

Corresponde a la etiqueta de autorización Tag::TRUSTED_CONFIRMATION_REQUIRED de Keymaster, que usa un valor de ID de etiqueta de 508.

Especifica que la clave solo se puede usar si el usuario proporciona confirmación de que los datos se firmarán con un token de aprobación. Para obtener más información acerca de cómo obtener confirmación del usuario, consulta Confirmación de protección de Android.

Nota: Esta etiqueta solo se aplica a claves que usan el propósito SIGN.

unlockedDeviceRequired

Solo está presente en la versión de certificación 3.

Corresponde a la etiqueta de autorización Tag::UNLOCKED_DEVICE_REQUIRED de Keymaster, que usa un valor de ID de etiqueta de 509.

allApplications

Corresponde a la etiqueta de autorización Tag::ALL_APPLICATIONS de Keymaster, que usa un valor de ID de etiqueta de 600.

Indica si todas las apps de un dispositivo pueden acceder al par de claves.

applicationId
Corresponde a la etiqueta de autorización Tag::APPLICATION_ID de Keymaster, que usa un valor de ID de etiqueta de 601.
creationDateTime
Corresponde a la etiqueta de autorización Tag::CREATION_DATETIME de Keymaster, que usa un valor de ID de etiqueta de 701.
origin

Corresponde a la etiqueta de autorización Tag::ORIGIN de Keymaster, que usa un valor de ID de etiqueta de 702.

rollbackResistant

Solo está presente en las versiones de certificación 1 y 2.

Corresponde a la etiqueta de autorización Tag::ROLLBACK_RESISTANT de Keymaster, que usa un valor de ID de etiqueta de 703.

rootOfTrust

Corresponde a la etiqueta de autorización Tag::ROOT_OF_TRUST de Keymaster, que usa un valor de ID de etiqueta de 704.

Para obtener más información, consulta la sección en la que se describe la estructura de datos de RootOfTrust.

osVersion

Corresponde a la etiqueta de autorización Tag::OS_VERSION de Keymaster, que usa un valor de ID de etiqueta de 705.

Es la versión del sistema operativo Android asociada con Keymaster, especificada como un número entero de seis dígitos. Por ejemplo, la versión 8.1.0 se representa como 080100.

Solo en la versión 1.0 o las versiones posteriores de Keymaster se incluye este valor en la lista de autorizaciones.

osPatchLevel

Corresponde a la etiqueta de autorización Tag::PATCHLEVEL de Keymaster, que usa un valor de ID de etiqueta de 706.

El mes y el año asociados con el parche de seguridad que se usa en Keymaster, especificados como un número entero de seis dígitos. Por ejemplo, el parche de agosto de 2018 se representa como 201808.

Solo en la versión 1.0 o las versiones posteriores de Keymaster se incluye este valor en la lista de autorizaciones.

attestationApplicationId

Solo está presente en las versiones de certificación 2 y 3.

Corresponde a la etiqueta de autorización Tag::ATTESTATION_APPLICATION_ID de Keymaster, que usa un valor de ID de etiqueta de 709.

Para obtener más información, consulta la sección en la que se describe la estructura de datos de AttestationApplicationId.

attestationIdBrand

Solo está presente en las versiones de certificación 2 y 3.

Corresponde a la etiqueta Tag::ATTESTATION_ID_BRAND de Keymaster, que usa un valor de ID de etiqueta de 701.

attestationIdDevice

Solo está presente en las versiones de certificación 2 y 3.

Corresponde a la etiqueta Tag::ATTESTATION_ID_DEVICE de Keymaster, que usa un valor de ID de etiqueta de 711.

attestationIdProduct

Solo está presente en las versiones de certificación 2 y 3.

Corresponde a la etiqueta Tag::ATTESTATION_ID_PRODUCT de Keymaster, que usa un valor de ID de etiqueta de 712.

attestationIdSerial

Solo está presente en las versiones de certificación 2 y 3.

Corresponde a la etiqueta Tag::ATTESTATION_ID_SERIAL de Keymaster, que usa un valor de ID de etiqueta de 713.

attestationIdImei

Solo está presente en las versiones de certificación 2 y 3.

Corresponde a la etiqueta de autorización Tag::ATTESTATION_ID_IMEI de Keymaster, que usa un valor de ID de etiqueta de 714.

attestationIdMeid

Solo está presente en las versiones de certificación 2 y 3.

Corresponde a la etiqueta de autorización Tag::ATTESTATION_ID_MEID de Keymaster, que usa un valor de ID de etiqueta de 715.

attestationIdManufacturer

Solo está presente en las versiones de certificación 2 y 3.

Corresponde a la etiqueta de autorización Tag::ATTESTATION_ID_MANUFACTURER de Keymaster, que usa un valor de ID de etiqueta de 716.

attestationIdModel

Solo está presente en las versiones de certificación 2 y 3.

Corresponde a la etiqueta Tag::ATTESTATION_ID_MODEL de Keymaster, que usa un valor de ID de etiqueta de 717.

vendorPatchLevel

Solo está presente en la versión de certificación 3.

Corresponde a la etiqueta de autorización Tag::VENDOR_PATCHLEVEL de Keymaster, que usa un valor de ID de etiqueta de 718.

Especifica el nivel de parche de seguridad de la imagen del proveedor que debe instalarse en el dispositivo para que se use esta clave. El valor aparece en el formato AAAAMMDD, que representa la fecha del parche de seguridad del proveedor. Por ejemplo, si una clave se hubiera generado en un dispositivo Android con el parche de seguridad del 1 de agosto de 2018 del proveedor instalado, este valor sería 20180801.

bootPatchLevel

Solo está presente en la versión de certificación 3.

Corresponde a la etiqueta de autorización Tag::BOOT_PATCHLEVEL de Keymaster, que usa un valor de ID de etiqueta de 719.

Especifica el nivel de parche de seguridad de la imagen del kernel que debe instalarse en el dispositivo para que se use esta clave. El valor aparece en el formato AAAAMMDD, que representa la fecha del parche de seguridad del sistema. Por ejemplo, si una clave se hubiera generado en un dispositivo Android con el parche de seguridad del 5 de agosto de 2018 del sistema instalado, este valor sería 20180805.

RootOfTrust

Este conjunto de valores define información clave sobre el estado del dispositivo.

Cada uno de los campos de la siguiente lista es obligatorio:

verifiedBootKey

Un hash seguro de la clave que verifica la imagen del sistema. Se recomienda que uses el algoritmo SHA-256 para este hash.

deviceLocked
Se presenta cuando el bootloader del dispositivo está bloqueado, lo cual habilita la comprobación de inicio verificado y evita que se transmita al dispositivo una imagen del dispositivo sin firmar. Para obtener más información sobre esta función, consulta la documentación de inicio verificado.
verifiedBootState
Estado de inicio del dispositivo, según la función de inicio verificado.
verifiedBootHash

Solo está presente en la versión de certificación 3.

Es un resumen de todos los datos protegidos por el inicio verificado. Para dispositivos que usan la implementación del inicio verificado de Android, este valor contiene el resumen de VBMeta struct, o la estructura de metadatos del inicio verificado.

Para obtener más información acerca de cómo calcular este valor, consulta el Resumen de VBMeta.

VerifiedBootState

Esta estructura de datos proporciona el estado de inicio actual del dispositivo, que representa el nivel de protección proporcionado al usuario y a las apps una vez que el dispositivo termina de iniciarse. Para obtener más información sobre esta función, consulta la sección del estado de inicio en la documentación del inicio verificado.

Esta estructura de datos es una enumeración, por lo cual adquiere exactamente uno de los siguientes valores:

Verificado

Indica una cadena completa de confianza, que incluye el bootloader, la partición de inicio y todas las particiones verificadas.

Cuando el dispositivo se encuentra en este estado de inicio, verifiedBootKey es el hash del certificado integrado en el dispositivo, que el fabricante de este último agrega a la ROM del dispositivo en la fábrica.

Autofirmado

Indica que el certificado integrado en el dispositivo verificó la partición de inicio del dispositivo y que la firma es válida.

Cuando el dispositivo se encuentra en este estado de inicio, verifiedBootKey es el hash de un certificado instalado por el usuario, que firma una partición de inicio que el usuario agrega al dispositivo en lugar de la partición de inicio original proporcionada por el fabricante.

Sin verificar
Indica que el usuario puede modificar el dispositivo libremente. Por lo tanto, el usuario es responsable de verificar la integridad del dispositivo.
Error
Indica que el dispositivo no superó la verificación. La certificación nunca debe usar este valor para VerifiedBootState.

AttestationApplicationId

Esta estructura de datos refleja la creencia de la plataforma de Android de que las apps pueden usar el material de clave secreta en la certificación. El ID puede comprender varios paquetes solo si estos comparten el mismo UID. La string del octeto se formatea según el siguiente esquema de ASN.1.

    AttestationApplicationId ::= SEQUENCE {
        package_infos  SET OF AttestationPackageInfo,
        signature_digests  SET OF OCTET_STRING,
    }

    AttestationPackageInfo ::= SEQUENCE {
        package_name  OCTET_STRING,
        version  INTEGER,
    }
package_infos
Es un conjunto de objetos AttestationPackageInfo, cada uno de los cuales proporciona un nombre de paquete y un número de versión.
signature_digests

Es un conjunto de resúmenes de SHA-256 de los blobs de firma de la app, como el que se incluye en el campo signatures de PackageInfo que se muestra ante una llamada a getPackageInfo(). El siguiente fragmento de código muestra un conjunto de ejemplo:

    {SHA256(PackageInfo.signature[0]), SHA256(PackageInfo.signature[1]), ...}