Skip to content

Most visited

Recently visited

navigation

Confirmação de chaves

A confirmação de chaves dá a você a confiança de que as chaves usadas no seu aplicativo sejam 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: Poucos dispositivos que executam o Android 7.0 (nível de API 24) oferecem suporte à confirmação de chaves no nível do hardware; todos os demais dispositivos que executam o Android 7.0 usam a confirmação de chaves no nível do software. 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 ofereça suporte à 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 que o elemento attestationSecurityLevel na estrutura de dados de descriptografia de chaves seja definido para o nível de segurança TrustedEnvironment.

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 oferecer suporte à confirmação de chaves no nível o 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) e o Google Play Services, o certificado raiz é assinado pela chave raiz de confirmação do Google. Você deve verificar se esse certificado raiz aparece na lista de certificados raiz do Google.

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

  1. Use o método getCertificateChain() de um objeto KeyStore para obter uma referência à cadeia de certificados X.509 associada ao armazenamento de chaves protegido por hardware.
  2. Verifique a validez de cada certificado usando um método isRevoked() de um objeto CRL.

    Atenção: Apesar de ser possível realizar esse processo diretamente no seu aplicativo, é mais seguro verificar as listas de revogação dos certificados em um servidor de confiança separado.

  3. Crie um objeto Attestation, passando o primeiro elemento da cadeia de certificados como um argumento:

    // "certificates" contains the certificate chain associated with a specific key
    // pair in the device's hardware-backed keystore.
    X509Certificate attestationCert = (X509Certificate) certificates[0];
    Attestation hardwareKeyAttestation = new Attestation(attestationCert);
    

    Um objeto de confirmação extrai os dados de extensão nesse certificado e armazena essas informações em um formato mais acessível. Para saber mais sobre o esquema dos dados de extensão, consulte Esquema de dados de extensão de certificado.

  4. Use os métodos de acesso na classe Attestation para recuperar os dados de extensão do certificado. Esses métodos usam os mesmos nomes e a hierarquia de estrutura do esquema de dados de extensão de certificado.

    Por exemplo, para visualizar a chave de inicialização verificada do TEE do dispositivo, use a seguinte sequência de métodos:

    // "hardwareKeyAttestation" contains the first element of the attestation
    // certificate chain.
    AuthorizationList teeAuthList = hardwareKeyAttestation.getTeeEnforced();
    RootOfTrust teeRootOfTrust = teeAuthList.getRootOfTrust();
    byte[] teeVerifiedBootKey = teeRootOfTrust.getVerifiedBootKey();
    
  5. Compare os dados de extensão do objeto Attestation 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 aplicativo, é mais seguro verificar os dados de extensão do certificado em um servidor de confiança separado.

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 o seguinte esquema ASN.1:

KeyDescription ::= SEQUENCE {
    attestationVersion  INTEGER,
    attestationSecurityLevel  SecurityLevel,
    keymasterVersion  INTEGER,
    keymasterSecurityLevel  SecurityLevel,
    attestationChallenge  OCTET_STRING,
    reserved  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,
    attestationChallenge  [708] EXPLICIT INTEGER OPTIONAL,
    attestationApplicationId  [709] EXPLICIT OCTET_STRING 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 detalhes adicionais.

attestationVersion
A versão do recurso de confirmação de chaves. Deve ser definido como 1.
attestationSecurityLevel

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

Aviso: Apesar de ser 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) 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.
attestationChallenge
A string de desafio associada a um par de chaves verificado usando a confirmação de chaves.
reserved
Somente aplicativos de sistema usam esse valor. Em todos os demais aplicativos, esse valor fica 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 em sua localização 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 aplicativo.
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 pois 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 aplicativo.

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 KM_TAG_KEY_SIZE do Keymaster.

Cada campo da lista a seguir é opcional:

purpose
Corresponde à tag KM_TAG_PURPOSE do Keymaster, que usa um valor de código de tag de 1.
algorithm

Corresponde à tag KM_TAG_ALGORITHM do Keymaster, que usa um valor de código de tag de 2.

Quando um objeto AuthorizationList é associado à confirmação de chaves, esse valor é sempre KM_ALGORITHM_RSA ou KM_ALGORITHM_EC.

keySize
Corresponde à tag KM_TAG_KEY_SIZE do Keymaster, que usa um valor de código de tag de 3.
digest
Corresponde à tag KM_TAG_DIGEST do Keymaster, que usa um valor de código de tag de 5.
padding
Corresponde à tag KM_TAG_PADDING do Keymaster, que usa um valor de código de tag de 6.
ecCurve

Corresponde à tag KM_TAG_EC_CURVE do Keymaster, que usa um valor de código de tag de 10.

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

rsaPublicExponent
Corresponde à tag KM_TAG_RSA_PUBLIC_EXPONENT do Keymaster, que usa um valor de código de tag de 200.
activeDateTime
Corresponde à tag KM_TAG_ACTIVE_DATETIME do Keymaster, que usa um valor de código de tag de 400.
originationExpireDateTime
Corresponde à tag KM_TAG_ORIGINATION_EXPIRE_DATETIME do Keymaster, que usa um valor de código de tag de 401.
usageExpireDateTime
Corresponde à tag KM_TAG_USAGE_EXPIRE_DATETIME do Keymaster, que usa um valor de código de tag de 402.
noAuthRequired

Corresponde à tag KM_TAG_NO_AUTH_REQUIRED do Keymaster, que usa um valor de código de tag de 503.

Quando um objeto AuthorizationList é associado à confirmação de chaves, esse valor é sempre true.

userAuthType
Corresponde à tag KM_TAG_USER_AUTH_TYPE do Keymaster, que usa um valor de código de tag de 504.
authTimeout
Corresponde à tag KM_TAG_AUTH_TIMEOUT do Keymaster, que usa um valor de código de tag de 505.
allowWhileOnBody

Corresponde à tag KM_TAG_ALLOW_WHILE_ON_BODY do Keymaster, que usa um valor de código de tag de 506.

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

Quando um objeto AuthorizationList é associado à confirmação de chaves, esse valor é sempre true.

allApplications

Corresponde à tag KM_TAG_ALL_APPLICATIONS do Keymaster, que usa um valor de código de tag de 600.

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

Quando um objeto AuthorizationList é associado à confirmação de chaves, esse valor é sempre true.

applicationId
Corresponde à tag KM_TAG_APPLICATION_ID do Keymaster, que usa um valor de código de tag de 601.
creationDateTime
Corresponde à tag KM_TAG_CREATION_DATETIME do Keymaster, que usa um valor de código de tag de 701.
origin

Corresponde à tag KM_TAG_ORIGIN do Keymaster, que usa um valor de código de tag de 702.

Quando um objeto AuthorizationList é associado à confirmação de chaves, esse valor é geralmente definido como KM_ORIGIN_GENERATED. Entretanto, se a confirmação usar o Keymaster versão 0.2 ou 0.3, a origem poderá ser definida como KM_ORIGIN_UNKNOWN.

rollbackResistant
Corresponde à tag KM_TAG_ROLLBACK_RESISTANT do Keymaster, que usa um valor de código de tag de 703.
rootOfTrust

Corresponde à tag KM_TAG_ROOT_OF_TRUST do Keymaster, que usa um valor de código de tag de 704.

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

osVersion

Corresponde à tag KM_TAG_OS_VERSION do Keymaster, que usa um valor de código de tag de 705.

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 6.0.1 é representada como 060001.

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

osPatchLevel

Corresponde à tag KM_TAG_PATCHLEVEL do Keymaster, que usa um valor de código de tag de 706.

O mês e o ano associados com o patch de segurança sendo usado no Keymaster, especificados como um número inteiro de seis dígitos. Por exemplo, o patch de junho de 2016 é representado como 201606.

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

attestationChallenge

Corresponde à tag KM_TAG_ATTESTATION_CHALLENGE do Keymaster, que usa um valor de código de tag de 708.

A string de desafio associada ao par de chaves definido no Keymaster.

attestationApplicationId

Corresponde à tag KM_TAG_ATTESTATION_APPLICATION_ID do Keymaster, que usa um valor de código de tag de 709.

O código exclusivo do certificado de confirmação que assinou o par de chaves que está no Keymaster.

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 bootloader 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.
verifiedBootState
O estado de inicialização do dispositivo, de acordo com o recurso de inicialização verificada.
osVersion
A versão atual do sistema operacional Android no dispositivo, especificada como um número inteiro de seis dígitos. Por exemplo, a versão 6.0.1 é representada como 060001.
patchMonthYear
O mês e o ano associados ao patch de segurança atualmente instalado no dispositivo, especificados como um número inteiro de seis dígitos. Por exemplo, o patch de agosto de 2016 é representado como 201608.

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 aplicativos após a 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 bootloader, 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 do dispositivo 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. O certificado de conformação nunca deve usar esse valor para VerifiedBootState.
This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Siga o Google Developers no WeChat

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience. (Dec 2017 Android Platform & Tools Survey)