Como verificar pares de chaves protegidos por hardware com confirmação de chaves

A confirmação de chaves dá a você a confiança de que as chaves usadas no seu app serão armazenadas em um armazenamento de chaves protegido por hardware de um dispositivo. As seções a seguir descrevem como verificar as propriedades de chaves protegidas por hardware e como interpretar o esquema dos dados de extensão do certificado de confirmação.

Observação: antes de verificar as propriedades das chaves protegidas por hardware de um dispositivo em um ambiente de produção, certifique-se de que o dispositivo seja compatível com a confirmação de chaves no nível do hardware. Para isso, verifique se a cadeia de certificados de confirmação contém um certificado raiz assinado pela chave raiz de confirmação do Google e se o elemento attestationSecurityLevel na estrutura de dados de descrição de chaves foi definido para o nível de segurança TrustedEnvironment.

Além disso, é importante verificar as assinaturas na cadeia de certificados e também se nenhuma das chaves na cadeia foi revogada conferindo a Lista de status de revogação de certificados. A menos que todas sejam válidas e a raiz seja a chave raiz do Google mencionada acima, não confie totalmente na confirmação. Observe, no entanto, que os dispositivos que contêm certificados revogados ainda são pelo menos tão confiáveis quanto os dispositivos que apenas são compatíveis com a confirmação de software. Ter uma confirmação totalmente válida é um forte indicador positivo. Não ter uma é um indicador neutro e não negativo.

Recuperar e verificar um par de chaves protegido por hardware

Durante a confirmação de chaves, você especifica o alias de um par de chaves. Por sua vez, a ferramenta de confirmação fornece uma cadeia de certificados, que você pode usar para verificar as propriedades desse par de chaves.

Se o dispositivo for compatível com a confirmação de chaves no nível de hardware, o certificado raiz nessa cadeia será assinado usando uma chave raiz de confirmação, que o fabricante do dispositivo injeta no armazenamento de chaves protegido por hardware do dispositivo na fábrica.

Observação: em dispositivos que incluem a confirmação de chaves no nível do hardware, o Android 7.0 (nível de API 24) ou posterior e o Google Play Services, o certificado raiz é assinado pela chave raiz de confirmação do Google. É preciso verificar se esse certificado raiz consta da lista abaixo.

Para implementar a confirmação de chaves, siga estas etapas:

  1. Use o método getCertificateChain() de um objeto KeyStore para conseguir uma referência à cadeia de certificados X.509 associada ao armazenamento de chaves protegido por hardware.
  2. Verifique a validade de cada certificado usando um método checkValidity() de um objeto X509Certificate. Além disso, verifique se o certificado raiz é confiável.

    Atenção: embora seja possível realizar esse processo diretamente no seu app, é mais seguro verificar o status de revogação dos certificados em um servidor de confiança separado.

  3. Em um servidor de confiança separado, use uma referência à biblioteca do analisador ASN.1 mais apropriada para seu conjunto de ferramentas. Use esse analisador para extrair os dados da extensão do certificado de confirmação, que aparece no primeiro elemento da cadeia de certificados.

    O exemplo Key Attestation (em inglês) usa o analisador ASN.1 do Bouncy Castle (em inglês) para extrair os dados de extensão de um certificado de confirmação. Use esse exemplo como referência para criar seu próprio analisador.

    Para saber mais sobre o esquema dos dados de extensão, consulte Esquema de dados de extensão de certificado.

  4. Compare os dados de extensão recuperados do analisador ASN.1 com o conjunto de valores que você espera que a chave protegida por hardware contenha.

    Atenção: apesar de ser possível realizar esse processo diretamente no seu app, é mais seguro verificar os dados de extensão do certificado em um servidor de confiança separado.

Certificados raiz

A confiabilidade da confirmação depende do certificado raiz da cadeia. Os dispositivos Android que foram aprovados no teste necessário para ter o conjunto de apps Google, incluindo o Google Play, e que foram lançados com o Android 7.0 (API de nível 24) ou posterior, precisam usar as chaves de confirmação assinadas pelo certificado raiz de confirmação de hardware do Google. Este certificado é:

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

Se o certificado raiz na cadeia de confirmação que você recebeu for o acima e nenhum dos certificados da cadeia tiver sido revogado, você saberá que:

  1. sua chave está no hardware que o Google acredita ser seguro; e
  2. ela tem as propriedades descritas no certificado de confirmação.

Se a cadeia de confirmação tiver qualquer outro certificado raiz, o Google não fará nenhuma declaração sobre a segurança do hardware. Isso não significa que sua chave esteja comprometida, apenas que a confirmação não prova que a chave está no hardware de segurança. Portanto, ajuste suas suposições de segurança de acordo com essa condição.

Se o certificado raiz não corresponde ao que está acima, há duas razões prováveis:

  • Provavelmente, o dispositivo foi lançado com uma versão do Android anterior à 7.0 e não é compatível com a confirmação de hardware. Nesse caso, o Android tem uma implementação de software de confirmação que produz o mesmo tipo de certificado de confirmação, mas que é assinado com uma chave fixada no código-fonte do Android. Como essa chave de assinatura não é um segredo, a confirmação poderia ter sido criada por um invasor que estivesse fingindo oferecer hardware seguro.
  • A outra razão provável é que o dispositivo não é do Google Play. Nesse caso, o criador do dispositivo é livre para criar a própria raiz e fazer as declarações que quiser sobre o significado da confirmação. Consulte a documentação do fabricante do dispositivo. Observe que, até o momento, o Google não tem conhecimento de fabricantes de dispositivos que fizeram isso.

Lista de status de revogação de certificado

As chaves de confirmação podem ser revogadas por vários motivos, inclusive manuseio incorreto ou extração suspeita por um invasor. Por esse motivo, é fundamental que o status de cada certificado em uma cadeia de confirmação seja verificado na lista oficial de status de revogação de certificado. Essa lista é mantida pelo Google e publicada em: https://android.googleapis.com/attestation/status. Esse URL retorna um arquivo JSON contendo o status de revogação para todos os certificados que não têm um status válido normal. O formato do arquivo JSON segue esta definição de esquema JSON (rascunho 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
    }

Exemplo de lista de status de revogação de certificado:

{
      "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"
        }
      }
    }
    

Listas de revogação de certificado legadas

Os URLs de lista de revogação de certificado (CRL, na sigla em inglês) incorporados nos certificados de confirmação legados continuarão funcionando. Os novos certificados de confirmação não terão mais uma extensão de URL da CRL. O status dos certificados legados também será incluído na lista de status de confirmação, para que os desenvolvedores tenham segurança para começar a usar a lista de status de confirmação para certificados novos e legados. Um exemplo de como verificar corretamente as chaves de confirmação do Android pode ser visto no exemplo Key Attestation (em inglês).

Esquema de dados de extensão de certificado

A confirmação de chaves verifica os dados de extensão que aparecem no primeiro certificado da cadeia de um armazenamento de chaves protegido por hardware de um dispositivo. O certificado armazena as informações de acordo com um esquema ASN.1. Para visualizar o esquema correspondente à versão de confirmação que você está usando, selecione a guia apropriada na seguinte lista de esquemas:

Versão 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),
    }
    

Versão 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),
    }
    

Versão 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),
    }
    

A lista a seguir apresenta uma descrição de cada elemento do esquema:

KeyDescription

Essa sequência de valores apresenta informações gerais sobre o par de chaves sendo verificado por meio da confirmação de chaves e oferece acesso fácil a outros detalhes.

attestationVersion
A versão do recurso de confirmação de chaves.
attestationSecurityLevel

O nível de segurança da confirmação.

Atenção: embora seja possível confirmar chaves armazenadas no sistema Android (ou seja, se o valor de attestationSecurityLevel estiver definido como Software), você não poderá confiar nessas confirmações se o sistema Android for comprometido.

keymasterVersion
A versão da camada de abstração de hardware (HAL, na sigla em inglês) do Keymaster. Use 0 para representar a versão 0.2 ou 0.3, 1 para representar a versão 1.0 e 2 para representar a versão 2.0.
keymasterSecurityLevel
O nível de segurança da implementação do Keymaster.
uniqueId
Esse valor identifica o dispositivo, mas apenas por um período limitado. É calculado e usado apenas por apps do sistema. Em todos os outros apps, uniqueId está vazio.
softwareEnforced
Opcional. A lista de autorização do Keymaster que é aplicada pelo sistema Android, não pelo TEE do dispositivo.
teeEnforced
Opcional. A lista de autorização do Keymaster que é aplicada pelo TEE do dispositivo.

SecurityLevel

Essa estrutura de dados indica até onde um recurso de software, como um par de chaves, é protegido com base na localização dele no dispositivo.

Como a estrutura de dados é uma enumeração, ela aceita um dos seguintes valores:

Software
A lógica para criar e gerenciar o recurso é implementada no sistema Android. Para os fins de criar e armazenar pares de chaves, essa localização é menos segura do que o TEE, mas mais segura do que o espaço de processamento do app.
TrustedEnvironment
A lógica para criar e gerenciar o recurso é implementada em um hardware protegido, como o TEE. Para os fins de criar e armazenar pares de chaves, essa localização é mais segura, porque um hardware protegido é altamente resistente ao comprometimento remoto.
StrongBox
A lógica para criar e gerenciar o recurso é implementada em um módulo de segurança de hardware dedicado. Para os fins de criar e armazenar pares de chaves, essa localização é mais segura, porque um hardware protegido é altamente resistente ao comprometimento remoto.

AuthorizationList

Essa estrutura de dados contém as propriedades do par de chaves, conforme são definidas na camada de abstração de hardware (HAL) do Keymaster. Você compara esses valores ao estado atual do dispositivo ou a um conjunto de valores esperados para verificar se um par de chaves ainda é válido para uso no seu app.

Cada nome de campo corresponde a uma tag do Keymaster com nome similar. Por exemplo, o campo keySize em uma lista de autorização corresponde à tag de autorização Tag::KEY_SIZE do Keymaster.

Cada campo da lista a seguir é opcional:

purpose
Corresponde à tag de autorização Tag::PURPOSE do Keymaster, que usa o valor 1 como código de tag.
algorithm

Corresponde à tag de autorização Tag::ALGORITHM do Keymaster, que usa o valor 2 como código de tag.

Em um objeto AuthorizationList de confirmação, o valor do algoritmo é sempre RSA ou EC.

keySize
Corresponde à tag de autorização Tag::KEY_SIZE do Keymaster, que usa o valor 3 como código de tag.
digest
Corresponde à tag de autorização Tag::DIGEST do Keymaster, que usa o valor 5 como código de tag.
padding
Corresponde à tag de autorização Tag::PADDING do Keymaster, que usa o valor 6 como código de tag.
ecCurve

Corresponde à tag de autorização Tag::EC_CURVE do Keymaster, que usa o valor 10 como código de tag.

O conjunto de parâmetros usados para criar um par de chaves de curva elíptica (EC, na sigla em inglês), que usa ECDSA para assinaturas e verificações, no armazenamento de chaves do sistema Android.

rsaPublicExponent
Corresponde à tag de autorização Tag::RSA_PUBLIC_EXPONENT do Keymaster, que usa o valor 200 como código de tag.
rollbackResistance

Presente apenas na versão 3 da confirmação de chaves.

Corresponde à tag de autorização Tag::ROLLBACK_RESISTANT do Keymaster, que usa o valor 303 como código de tag.

activeDateTime
Corresponde à tag de autorização Tag::ACTIVE_DATETIME do Keymaster, que usa o valor 400 como código de tag.
originationExpireDateTime
Corresponde à tag de autorização Tag::ORIGINATION_EXPIRE_DATETIME do Keymaster, que usa o valor 401 como código de tag.
usageExpireDateTime
Corresponde à tag de autorização Tag::USAGE_EXPIRE_DATETIME do Keymaster, que usa o valor 402 como código de tag.
noAuthRequired

Corresponde à tag de autorização Tag::NO_AUTH_REQUIRED do Keymaster, que usa o valor 503 como código de tag.

userAuthType
Corresponde à tag de autorização Tag::USER_AUTH_TYPE do Keymaster, que usa o valor 504 como código de tag.
authTimeout
Corresponde à tag de autorização Tag::AUTH_TIMEOUT do Keymaster, que usa o valor 505 como código de tag.
allowWhileOnBody

Corresponde à tag de autorização Tag::ALLOW_WHILE_ON_BODY do Keymaster, que usa o valor 506 como código de tag.

Permite que a chave seja usada após o tempo limite de autenticação se o usuário ainda estiver usando o dispositivo no corpo. Observe que um sensor corporal seguro determina se o dispositivo está sendo usado pelo usuário.

trustedUserPresenceRequired

Presente apenas na versão 3 da confirmação de chaves.

Corresponde à tag de autorização Tag::TRUSTED_USER_PRESENCE_REQUIRED do Keymaster, que usa o valor 507 como código de tag.

Especifica que essa chave será utilizável apenas se o usuário tiver fornecido prova de presença física. Entre os exemplos estão os seguintes:

  • Para uma chave StrongBox, um botão físico é conectado a um pino no dispositivo StrongBox.
  • Para uma chave TEE, a autenticação por impressão digital fornece prova de presença, desde que o TEE tenha controle exclusivo do scanner e realize o processo de correspondência de impressão digital.
trustedConfirmationRequired

Presente apenas na versão 3 da confirmação de chaves.

Corresponde à tag de autorização Tag::TRUSTED_CONFIRMATION_REQUIRED do Keymaster, que usa o valor 508 como código de tag.

Especifica que a chave será utilizável apenas se o usuário fornecer confirmação dos dados a serem assinados usando um token de aprovação. Para mais informações sobre como conseguir a confirmação do usuário, consulte Confirmação protegida pelo Android.

Observação: essa tag é válida apenas para chaves que usam a finalidade SIGN.

unlockedDeviceRequired

Presente apenas na versão 3 da confirmação de chaves.

Corresponde à tag de autorização Tag::UNLOCKED_DEVICE_REQUIRED do Keymaster, que usa o valor 509 como código de tag.

allApplications

Corresponde à tag de autorização Tag::ALL_APPLICATIONS do Keymaster, que usa o valor 600 como código de tag.

Indica se todos os apps de um dispositivo podem acessar o par de chaves.

applicationId
Corresponde à tag de autorização Tag::APPLICATION_ID do Keymaster, que usa o valor 601 como código de tag.
creationDateTime
Corresponde à tag de autorização Tag::CREATION_DATETIME do Keymaster, que usa o valor 701 como código de tag.
origin

Corresponde à tag de autorização Tag::ORIGIN do Keymaster, que usa o valor 702 como código de tag.

rollbackResistant

Presente apenas nas versões 1 e 2 da confirmação de chaves.

Corresponde à tag de autorização Tag::ROLLBACK_RESISTANT do Keymaster, que usa o valor 703 como código de tag.

rootOfTrust

Corresponde à tag de autorização Tag::ROOT_OF_TRUST do Keymaster, que usa o valor 704 como código de tag.

Para mais detalhes, consulte a seção que descreve a estrutura de dados RootOfTrust.

osVersion

Corresponde à tag de autorização Tag::OS_VERSION do Keymaster, que usa o valor 705 como código de tag.

A versão do sistema operacional Android associado ao Keymaster, especificada como um número inteiro de seis dígitos. Por exemplo, a versão 8.1.0 é representada como 080100.

Somente o Keymaster versão 1.0 ou mais recente inclui esse valor na lista de autorizações.

osPatchLevel

Corresponde à tag de autorização Tag::PATCHLEVEL do Keymaster, que usa o valor 706 como código de tag.

O mês e o ano associados com o patch de segurança que está sendo usado no Keymaster, especificados como um número inteiro de seis dígitos. Por exemplo, o patch de agosto de 2018 é representado como 201808.

Somente o Keymaster versão 1.0 ou posterior inclui esse valor na lista de autorizações.

attestationApplicationId

Presente apenas nas versões de 2 e 3 da confirmação de chaves.

Corresponde à tag de autorização Tag::ATTESTATION_APPLICATION_ID do Keymaster, que usa o valor 709 como código de tag.

Para mais detalhes, consulte a seção que descreve a estrutura de dados AttestationApplicationId.

attestationIdBrand

Presente apenas nas versões de 2 e 3 da confirmação de chaves.

Corresponde à tag Tag::ATTESTATION_ID_BRAND do Keymaster, que usa o valor 710 como código de tag.

attestationIdDevice

Presente apenas nas versões de 2 e 3 da confirmação de chaves.

Corresponde à tag Tag::ATTESTATION_ID_DEVICE do Keymaster, que usa o valor 711 como código de tag.

attestationIdProduct

Presente apenas nas versões de 2 e 3 da confirmação de chaves.

Corresponde à tag Tag::ATTESTATION_ID_PRODUCT do Keymaster, que usa o valor 712 como código de tag.

attestationIdSerial

Presente apenas nas versões de 2 e 3 da confirmação de chaves.

Corresponde à tag Tag::ATTESTATION_ID_SERIAL do Keymaster, que usa o valor 713 como código de tag.

attestationIdImei

Presente apenas nas versões de 2 e 3 da confirmação de chaves.

Corresponde à tag de autorização Tag::ATTESTATION_ID_IMEI do Keymaster, que usa o valor 714 como código de tag.

attestationIdMeid

Presente apenas nas versões de 2 e 3 da confirmação de chaves.

Corresponde à tag de autorização Tag::ATTESTATION_ID_MEID do Keymaster, que usa o valor 715 como código de tag.

attestationIdManufacturer

Presente apenas nas versões de 2 e 3 da confirmação de chaves.

Corresponde à tag de autorização Tag::ATTESTATION_ID_MANUFACTURER do Keymaster, que usa o valor 716 como código de tag.

attestationIdModel

Presente apenas nas versões de 2 e 3 da confirmação de chaves.

Corresponde à tag Tag::ATTESTATION_ID_MODEL do Keymaster, que usa o valor 717 como código de tag.

vendorPatchLevel

Presente apenas na versão 3 da confirmação de chaves.

Corresponde à tag de autorização Tag::VENDOR_PATCHLEVEL do Keymaster, que usa o valor 718 como código de tag.

Especifica o nível de patch de segurança da imagem do fornecedor que precisa ser instalado no dispositivo para que essa chave seja usada. O valor aparece no formato AAAAMMDD, que representa a data do patch de segurança do fornecedor. Por exemplo, se uma chave fosse gerada em um dispositivo Android com o patch de segurança do fornecedor de 1º de agosto de 2018 instalado, esse valor seria 20180801.

bootPatchLevel

Presente apenas na versão 3 da confirmação de chaves.

Corresponde à tag de autorização Tag::BOOT_PATCHLEVEL do Keymaster, que usa o valor 719 como código de tag.

Especifica o nível de patch de segurança da imagem do kernel que precisa ser instalado no dispositivo para que essa chave seja usada. O valor aparece no formato AAAAMMDD, que representa a data do patch de segurança do sistema. Por exemplo, se uma chave fosse gerada em um dispositivo Android com o patch de segurança do sistema de 5 de agosto de 2018 instalado, esse valor seria 20180805.

RootOfTrust

Esse conjunto de valores define informações essenciais sobre o status do dispositivo.

Cada campo da lista a seguir é obrigatório:

verifiedBootKey

Um hash seguro da chave que verifica a imagem do sistema. Recomenda-se o uso do algoritmo SHA-256 para esse hash.

deviceLocked
True se o carregador de inicialização do dispositivo estiver bloqueado, o que ativa a verificação da "Inicialização verificada" e impede que uma imagem de dispositivo não assinada seja reproduzida no dispositivo. Para saber mais sobre esse recurso, consulte a documentação Verificar inicialização (link em inglês).
verifiedBootState
O estado de inicialização do dispositivo, de acordo com o recurso "Inicialização verificada".
verifiedBootHash

Presente apenas na versão 3 da confirmação de chaves.

Um resumo de todos os dados protegidos pela Inicialização verificada. Para dispositivos que usam a implementação de "Inicialização verificada" do Android, esse valor contém o resumo da estrutura VBMeta ou a estrutura de metadados da "Inicialização verificada".

Para saber mais sobre como calcular esse valor, consulte Resumo do VBMeta (link em inglês).

VerifiedBootState

Essa estrutura de dados fornece o estado de inicialização atual do dispositivo, que representa o nível de proteção fornecido ao usuário e aos apps depois da conclusão da inicialização do dispositivo. Para saber mais sobre esse recurso, consulte a seção Estado de inicialização da documentação "Verificar inicialização".

Essa estrutura de dados é uma enumeração, portanto, ela aceita um dos seguintes valores:

Verified

Indica uma cadeia completa de confiança, que inclui o carregador de inicialização, a partição de inicialização e todas as partições verificadas.

Quando o dispositivo se encontra nesse estado de inicialização, o verifiedBootKey é o hash do certificado incorporado ao dispositivo, que é adicionado pelo fabricante à ROM do dispositivo na fábrica.

SelfSigned

Indica que o certificado incorporado ao dispositivo verificou a partição de inicialização e que a assinatura é válida.

Quando o dispositivo se encontra nesse estado de inicialização, o verifiedBootKey é o hash do certificado instalado pelo usuário, que assina uma partição de inicialização que o usuário adiciona ao dispositivo no lugar da partição de inicialização original fornecida pelo fabricante.

Unverified
Indica que o usuário pode modificar o dispositivo livremente. Portanto, o usuário é responsável por verificar a integridade do dispositivo.
Failed
Indica que a verificação do dispositivo falhou. Recomenda-se que o certificado de confirmação nunca use esse valor para VerifiedBootState.

AttestationApplicationId

Essa estrutura de dados reflete a crença da plataforma Android sobre quais apps podem usar o material de chave secreta em confirmação. O código poderá incluir vários pacotes somente se os diversos pacotes compartilharem o mesmo UID. A string de octetos é formatada de acordo com o seguinte esquema 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
Um conjunto de objetos AttestationPackageInfo, cada um fornecendo um nome de pacote e um número de versão.
signature_digests

Um conjunto de SHA-256 digere os blobs de assinatura do app, contidos no campo signatures do PackageInfo que é retornado depois de uma chamada para getPackageInfo(). O snippet de código a seguir mostra um conjunto de exemplos:

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