Atributos

Esta página contém informações sobre os recursos criptográficos do Keystore do Android, conforme fornecido pela implementação do KeyMint (ou Keymaster) subjacente.

Primitivos criptográficos

O Keystore oferece as seguintes categorias de operações:

  • Criação de chaves, resultando em material de chave privada ou secreta que é acessível apenas ao ambiente seguro. Os clientes podem criar chaves das seguintes maneiras:
    • Geração de chaves novas
    • Importação de material de chave não criptografado
    • Importação de material de chave criptografado
  • Atestado de chave: a criação de chaves assimétricas gera um certificado que contém a parte pública do par de chaves. Esse certificado também pode conter informações sobre os metadados da chave e o estado do dispositivo, tudo assinado por uma chave que se conecta a uma raiz confiável.
  • Operações criptográficas:
    • Criptografia e descriptografia simétricas (AES, 3DES)
    • Descriptografia assimétrica (RSA)
    • Assinatura assimétrica (ECDSA, RSA)
    • Assinatura e verificação simétricas (HMAC)
    • Acordo de chave assimétrica (ECDH)

Elementos de protocolo, como finalidade, modo e preenchimento, além de restrições de controle de acesso, são especificados quando as chaves são geradas ou importadas e são permanentemente vinculadas à chave, garantindo que ela não possa ser usada de outra maneira.

As primitivas e os modos que precisam ser compatíveis com a implementação do KeyMint são descritos na especificação da interface HAL IKeyMintDevice.

A implementação do KeyMint precisa realizar a geração de números aleatórios para oferecer suporte à geração de chaves e à criação de preenchimento aleatório ou vetores de inicialização (IVs, na sigla em inglês). Para isso, o sistema Android fornece periodicamente entropia adicional à implementação do KeyMint.

Controle de acesso de chaves

As chaves baseadas em hardware que nunca podem ser extraídas do dispositivo não oferecem muita segurança se um invasor puder usá-las à vontade, embora sejam mais seguras do que as chaves que podem ser exfiltradas. Portanto, é crucial que o Keystore aplique controles de acesso.

Os controles de acesso são definidos como uma "lista de autorização" de pares de tag/valor. As tags de autorização são números inteiros de 32 bits, e os valores são de vários tipos. Algumas tags podem ser repetidas para especificar vários valores. Se uma tag pode ser repetida é especificado na interface HAL do KeyMint (anteriormente Keymaster).

Os valores de tag compatíveis são definidos no arquivo Tag.aidl, e cada um está associado a um TagType que indica o tipo do valor associado (por exemplo, inteiro ou bytes) e se ele pode ser repetido para especificar vários valores compatíveis.

Quando o KeyMint cria uma chave, o autor da chamada especifica uma lista de autorização para a chave. Essa lista é modificada pelo Keystore e pelo KeyMint para adicionar outras restrições, e a implementação do KeyMint codifica a lista de autorização final no blob de chaves retornado. A lista de autorização codificada é vinculada criptograficamente ao keyblob, de modo que qualquer tentativa de modificar a lista de autorização (incluindo a ordenação) resulta em um keyblob inválido que não pode ser usado para operações criptográficas.

Aplicação de hardware x software

Nem todas as implementações de hardware seguro contêm os mesmos recursos. Para oferecer suporte a uma variedade de abordagens, o KeyMint distingue entre a aplicação de controle de acesso seguro e não seguro, ou aplicação de hardware e software, respectivamente.

Isso é exposto na API KeyMint com o campo securityLevel do tipo KeyCharacteristics. O hardware seguro é responsável por colocar as autorizações no KeyCharacteristics com o nível de segurança adequado, com base no que ele pode aplicar. Essas informações também são expostas nos registros de atestado para chaves assimétricas: as características de chave para SecurityLevel::TRUSTED_ENVIRONMENT ou SecurityLevel::STRONGBOX aparecem na lista hardwareEnforced, e as características para SecurityLevel::SOFTWARE ou SecurityLevel::KEYSTORE aparecem na lista softwareEnforced.

Por exemplo, as restrições no intervalo de data e hora em que uma chave pode ser usada normalmente não são aplicadas pelo ambiente seguro, porque ele não tem acesso confiável às informações de data e hora. Como resultado, autorizações como Tag::ORIGINATION_EXPIRE_DATETIME são aplicadas pelo Keystore no Android e têm SecurityLevel::KEYSTORE.

Para mais informações sobre como determinar se as chaves e as autorizações delas são apoiadas por hardware, consulte Atestado de chave.

Autorizações de construção de mensagens criptográficas

As tags a seguir são usadas para definir as características criptográficas das operações que usam a chave associada:

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

As tags a seguir são repetíveis, o que significa que vários valores podem ser associados a uma única chave:

  • Tag::BLOCK_MODE
  • Tag::PADDING
  • Tag::DIGEST
  • Tag::MGF_DIGEST

O valor a ser usado é especificado no momento da operação.

Finalidade

As chaves têm um conjunto de finalidades associadas, expressas como uma ou mais entradas de autorização com a tag Tag::PURPOSE, que define como elas podem ser usadas. As finalidades são definidas em KeyPurpose.aidl.

Algumas combinações de valores de finalidade criam problemas de segurança. Por exemplo, uma chave RSA que pode ser usada para criptografar e assinar permite que um invasor que possa convencer o sistema a descriptografar dados arbitrários gere assinaturas.

Importação de chave

O KeyMint oferece suporte à importação de:

  • Pares de chaves assimétricas no formato PKCS#8 codificado em DER (sem criptografia baseada em senha)
  • Chaves simétricas como bytes brutos

Para garantir que as chaves importadas possam ser diferenciadas das chaves geradas com segurança, Tag::ORIGIN é incluído na lista de autorização de chaves apropriada. Por exemplo, se uma chave foi gerada em hardware seguro, Tag::ORIGIN com o valor KeyOrigin::GENERATED é encontrado na lista hw_enforced das características da chave, enquanto uma chave importada para hardware seguro tem o valor KeyOrigin::IMPORTED.

Autenticação do usuário

As implementações seguras do KeyMint não implementam a autenticação do usuário, mas dependem de outros apps confiáveis que fazem isso. Para ver a interface que esses apps implementam, consulte a página do Gatekeeper.

Os requisitos de autenticação do usuário são especificados por dois conjuntos de tags. O primeiro conjunto indica quais métodos de autenticação permitem o uso da chave:

  • Tag::USER_SECURE_ID tem um valor numérico de 64 bits que especifica o ID do usuário seguro fornecido em um token de autenticação seguro para desbloquear o uso da chave. Se repetida, a chave poderá ser usada se algum dos valores for fornecido em um token de autenticação seguro.

O segundo conjunto indica se e quando o usuário precisa ser autenticado. Se nenhuma dessas tags estiver presente, mas Tag::USER_SECURE_ID estiver, a autenticação será necessária para cada uso da chave.

  • Tag::NO_AUTHENTICATION_REQUIRED indica que nenhuma autenticação de usuário é necessária, embora o acesso à chave ainda seja restrito ao app proprietário (e a todos os apps aos quais ele concede acesso).
  • Tag::AUTH_TIMEOUT é um valor numérico que especifica, em segundos, o tempo de validade da autenticação do usuário para autorizar o uso da chave. Os tempos limite não são mantidos após as reinicializações. Depois de uma reinicialização, todas as autenticações são invalidadas. O tempo limite pode ser definido como um valor grande para indicar que a autenticação é necessária uma vez por inicialização (2^32 segundos é ~136 anos; presumivelmente, os dispositivos Android são reinicializados com mais frequência do que isso).

Exigir um dispositivo desbloqueado

As chaves com Tag::UNLOCKED_DEVICE_REQUIRED só podem ser usadas enquanto o dispositivo está desbloqueado. Para ver a semântica detalhada, consulte KeyProtection.Builder#setUnlockedDeviceRequired(boolean).

UNLOCKED_DEVICE_REQUIRED é aplicada pelo Keystore, não pelo KeyMint. No entanto, no Android 12 e versões mais recentes, o Keystore protege criptograficamente as chaves UNLOCKED_DEVICE_REQUIRED enquanto o dispositivo está bloqueado para garantir que, na maioria dos casos, elas não possam ser usadas, mesmo que o Keystore seja comprometido enquanto o dispositivo está bloqueado.

Toda a criptografia e geração de números aleatórios descritas nesta seção usam o BoringSSL, exceto quando o uso do KeyMint é explicitamente mencionado. Todos os secrets são zerados assim que não são mais necessários.

Superchaves UnlockedDeviceRequired

Para proteger as chaves UNLOCKED_DEVICE_REQUIRED de forma criptográfica, o Keystore as "supercriptografa" antes de armazená-las no banco de dados. Quando possível, ele protege as chaves de supercriptografia (superchaves) enquanto o dispositivo está bloqueado, de modo que elas só possam ser recuperadas por um desbloqueio bem-sucedido do dispositivo. O termo "supercriptografia" é usado porque essa camada de criptografia é aplicada além da camada de criptografia que o KeyMint já aplica a todas as chaves.

Cada usuário (incluindo perfis) tem duas superchaves associadas a UNLOCKED_DEVICE_REQUIRED:

  • A superchave simétrica UnlockedDeviceRequired. Essa é uma chave AES‑256‑GCM. Ele criptografa as chaves do UNLOCKED_DEVICE_REQUIRED que são importadas, geradas ou usadas enquanto o dispositivo está desbloqueado para o usuário.
  • A superchave assimétrica UnlockedDeviceRequired. Este é um par de chaves ECDH P-521. Ele criptografa as chaves UNLOCKED_DEVICE_REQUIRED importadas ou geradas enquanto o dispositivo está bloqueado para o usuário. Para mais detalhes, consulte Armazenar chaves enquanto o dispositivo está bloqueado.

Como gerar e proteger as superchaves

Quando um usuário é criado, o Keystore gera as superchaves UnlockedDeviceRequired do usuário e as armazena no banco de dados, criptografadas (indiretamente) pela senha sintética do usuário:

  1. O servidor do sistema deriva a senha do Keystore do usuário da senha sintética usando uma KDF SP800-108.
  2. O servidor do sistema transmite a senha do Keystore do usuário para o Keystore.
  3. O Keystore gera as superchaves do usuário.
  4. Para cada uma das superchaves do usuário:
    1. O Keystore gera um salt aleatório.
    2. O Keystore deriva uma chave AES-256-GCM da senha do Keystore do usuário e do salt usando HKDF-SHA256.
    3. O Keystore criptografa a parte secreta da superchave usando essa chave AES‑256‑GCM.
    4. O Keystore armazena a superchave criptografada e o salt dela no banco de dados. Se for uma chave assimétrica, a metade pública dela também será armazenada sem criptografia.

Esse procedimento permite que essas superchaves sejam descriptografadas quando a senha sintética do usuário é conhecida, como quando o PIN, o padrão ou a senha corretos do usuário são inseridos.

O Keystore também armazena em cache essas superchaves na memória, permitindo que ele opere em chaves UNLOCKED_DEVICE_REQUIRED. No entanto, ele tenta armazenar em cache as partes secretas dessas chaves apenas enquanto o dispositivo está desbloqueado para o usuário. Quando o dispositivo é bloqueado para o usuário, o Keystore zera a cópia em cache das partes secretas dessas superchaves, se possível. Especificamente, quando o dispositivo está bloqueado para o usuário, o Keystore seleciona e aplica um dos três níveis de proteção para as superchaves UnlockedDeviceRequired do usuário:

  • Se o usuário tiver apenas PIN, padrão ou senha ativados, o Keystore vai zerar as partes secretas das superchaves armazenadas em cache. Isso torna as superchaves recuperáveis apenas pela cópia criptografada no banco de dados, que pode ser descriptografada apenas por PIN, padrão ou senha equivalente.
  • Se o usuário tiver apenas biometria de classe 3 ("forte") e PIN, padrão ou senha ativados, o Keystore vai organizar as superchaves para que sejam recuperáveis por qualquer uma das biometrias de classe 3 registradas do usuário (geralmente impressão digital), como uma alternativa ao PIN, padrão ou senha equivalente. Para fazer isso, ele gera uma nova chave AES‑256‑GCM, criptografa as partes secretas das superchaves com ela, importa a chave AES‑256‑GCM para o KeyMint como uma chave vinculada à biometria que exige que a autenticação biométrica tenha sido realizada nos últimos 15 segundos e zera as cópias em texto simples de todas essas chaves.
  • Se o usuário tiver uma biometria de classe 1 ("conveniência"), de classe 2 ("fraca") ou um agente de confiança de desbloqueio ativo, o Keystore vai manter as superchaves armazenadas em cache em texto simples. Nesse caso, a segurança criptográfica para as chaves UNLOCKED_DEVICE_REQUIRED não é fornecida. Os usuários podem evitar esse substituto menos seguro não ativando esses métodos de desbloqueio. Os métodos de desbloqueio mais comuns que se enquadram nessas categorias são o desbloqueio facial em muitos dispositivos e o desbloqueio com um smartwatch pareado.

Quando o dispositivo é desbloqueado para o usuário, o Keystore recupera as superchaves UnlockedDeviceRequired do usuário, se possível. Para o desbloqueio equivalente por PIN, padrão ou senha, ele descriptografa a cópia dessas chaves que está armazenada no banco de dados. Caso contrário, ele verifica se salvou uma cópia dessas chaves criptografadas com uma chave vinculada à biometria e, se sim, tenta descriptografá-la. Isso só vai funcionar se o usuário tiver se autenticado com uma biometria de classe 3 nos últimos 15 segundos, aplicada pelo KeyMint (não pelo Keystore).

Armazenamento de chaves enquanto o dispositivo está bloqueado

O Keystore permite que os usuários importem e gerem chaves UNLOCKED_DEVICE_REQUIRED enquanto o dispositivo está bloqueado. Ele usa um esquema de criptografia híbrida para garantir que eles só possam ser descriptografados quando o dispositivo for desbloqueado:

  • Criptografia (importação ou geração de uma chave UNLOCKED_DEVICE_REQUIRED enquanto o dispositivo está bloqueado):
    1. O Keystore gera um novo par de chaves ECDH P-521 temporário.
    2. O Keystore gera um segredo compartilhado fazendo um acordo de chaves ECDH entre a chave privada desse par de chaves temporário e a metade pública da superchave assimétrica UnlockedDeviceRequired.
    3. O Keystore gera um salt aleatório.
    4. O Keystore deriva uma chave AES‑256‑GCM da chave secreta compartilhada e do salt usando HKDF‑SHA256.
    5. O Keystore criptografa a chave UNLOCKED_DEVICE_REQUIRED usando essa chave AES‑256‑GCM.
    6. O Keystore armazena a chave UNLOCKED_DEVICE_REQUIRED criptografada, o sal e a metade pública do par de chaves temporárias no banco de dados.
  • Descriptografia (usando a chave UNLOCKED_DEVICE_REQUIRED criada enquanto o dispositivo está desbloqueado):
    1. O Keystore carrega a chave UNLOCKED_DEVICE_REQUIRED criptografada, o sal e a metade pública do par de chaves temporárias do banco de dados.
    2. O Keystore gera um segredo compartilhado fazendo um acordo de chaves ECDH entre a metade pública do par de chaves temporário e a metade privada da superchave assimétrica UnlockedDeviceRequired. A chave privada está disponível porque o dispositivo está desbloqueado.
    3. O Keystore deriva uma chave AES‑256‑GCM da chave secreta compartilhada e do salt usando HKDF‑SHA256. Essa chave AES‑256‑GCM é igual à que foi derivada durante a criptografia.
    4. O Keystore descriptografa a chave UNLOCKED_DEVICE_REQUIRED usando a chave AES‑256‑GCM.
    5. O Keystore criptografa novamente a chave UNLOCKED_DEVICE_REQUIRED usando a superchave simétrica UnlockedDeviceRequired. Isso não afeta as propriedades de segurança da chave, mas permite que ela seja acessada mais rapidamente depois.

Esse recurso permite que os apps armazenem dados enquanto o dispositivo está bloqueado, de modo que eles só possam ser descriptografados quando o dispositivo estiver desbloqueado. Para fazer isso, os apps precisam seguir estas etapas:

  1. Gere uma chave AES‑256‑GCM fora do Keystore.
  2. Criptografe dados usando a chave AES‑256‑GCM.
  3. Importe a chave AES-256-GCM para o Keystore com o conjunto de proteção de chaves setUnlockedDeviceRequired(true).
  4. Zere a cópia original da chave.

Para descriptografar os dados enquanto o dispositivo estiver desbloqueado, use a chave que foi importada para o Keystore.

Vinculação de cliente

A vinculação do cliente, a associação de uma chave a um app cliente específico, é feita por um ID do cliente opcional e alguns dados do cliente opcionais (Tag::APPLICATION_ID e Tag::APPLICATION_DATA, respectivamente). O Keystore trata esses valores como blobs opacos, garantindo apenas que os mesmos blobs apresentados durante a geração/importação de chaves sejam apresentados para cada uso e sejam idênticos byte por byte. Os dados de vinculação do cliente não são retornados pelo KeyMint. O autor da chamada precisa saber disso para usar a chave.

Esse recurso não é exposto aos apps.

Expiração

O Keystore permite restringir o uso de chaves por data. O início da validade e as expirações de chaves podem ser associados a uma chave, e o Keystore se recusa a realizar operações de chave se a data/hora atual estiver fora do intervalo válido. O intervalo de validade da chave é especificado com as tags Tag::ACTIVE_DATETIME, Tag::ORIGINATION_EXPIRE_DATETIME e Tag::USAGE_EXPIRE_DATETIME. A distinção entre "origem" e "uso" é baseada no fato de a chave estar sendo usada para "originar" um novo texto criptografado/assinatura/etc. ou para "usar" um texto criptografado/assinatura/etc. existente. Essa distinção não é exposta aos apps.

As tags Tag::ACTIVE_DATETIME, Tag::ORIGINATION_EXPIRE_DATETIME e Tag::USAGE_EXPIRE_DATETIME são opcionais. Se as tags estiverem ausentes, presume-se que a chave em questão sempre pode ser usada para descriptografar/verificar mensagens.

Como o horário do relógio de parede é fornecido pelo mundo não seguro, as tags relacionadas à validade estão na lista de aplicação por software.

Vinculação da raiz de confiança

O Keystore exige que as chaves sejam vinculadas a uma raiz de confiança, que é uma string de bits fornecida ao hardware seguro do KeyMint durante a inicialização, de preferência pelo carregador de inicialização. Essa string de bits é vinculada criptograficamente a todas as chaves gerenciadas pelo KeyMint.

A raiz de confiança consiste no hash da chave pública usada para verificar a assinatura na imagem de inicialização e o estado de bloqueio do dispositivo. Se a chave pública for alterada para permitir o uso de uma imagem do sistema diferente ou se o estado de bloqueio for alterado, nenhuma das chaves protegidas pelo KeyMint criadas pelo sistema anterior poderá ser usada, a menos que a raiz de confiança anterior seja restaurada e um sistema assinado por essa chave seja inicializado. O objetivo é aumentar o valor dos controles de acesso à chave aplicados por software, impossibilitando que um sistema operacional instalado por um invasor use as chaves do KeyMint.

Nova propagação do gerador de números aleatórios

Como o hardware seguro gera números aleatórios para material de chave e vetores de inicialização (IVs, na sigla em inglês) e como os geradores de números aleatórios de hardware nem sempre são totalmente confiáveis, a HAL do KeyMint oferece uma interface para permitir que o Keystore forneça entropia adicional, que é misturada aos números aleatórios gerados.

Use um gerador de números aleatórios de hardware como a principal fonte de sementes. Os dados de semente fornecidos pela API externa não podem ser a única fonte de aleatoriedade usada para a geração de números. Além disso, a operação de mistura usada precisa garantir que a saída aleatória seja imprevisível se qualquer uma das fontes de semente for imprevisível.