Atributos

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

Primitivos criptográficos

O keystore fornece 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 criptografada
  • Atestado de chave: a criação de chave assimétrica gera um certificado que contém a parte de chave pública do par de chaves. Opcionalmente, esse certificado também contém informações sobre os metadados da chave e o estado do dispositivo, tudo assinado por uma cadeia de chaves de volta para 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)

O keystore e o KeyMint não processam operações de chave pública para chaves assimétricas.

Elementos do protocolo, como finalidade, modo e preenchimento, bem como 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 a chave não possa ser usada de nenhuma 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 de KeyMint precisa realizar a geração de números aleatórios para oferecer suporte à geração de chaves e à criação de padding aleatório ou vetores de inicialização (IVs). Para oferecer suporte a isso, o sistema Android fornece periodicamente entropia adicional à implementação do KeyMint.

Controle de acesso principal

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. No entanto, elas são mais seguras do que as chaves que podem ser exfiltradas. Portanto, é essencial 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. A possibilidade de repetição de uma tag é especificada na interface HAL do KeyMint (anteriormente Keymaster).

Os valores de tag com suporte são definidos no arquivo Tag.aidl, e cada um deles é 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 com suporte.

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

Aplicação de software versus hardware

Nem todas as implementações de hardware seguro têm os mesmos recursos. Para oferecer suporte a várias abordagens, o KeyMint distingue entre a aplicação de controle de acesso segura e não segura, ou a 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 geralmente 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 teriam SecurityLevel::KEYSTORE.

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

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, ou seja, 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 associado de finalidades, expressas como uma ou mais entradas de autorização com a tag Tag::PURPOSE, que define como elas podem ser usadas. Os propósitos são definidos 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 criptografia e assinatura permite que um atacante convença o sistema a descriptografar dados arbitrários para gerar 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 distinguidas das chaves geradas com segurança, Tag::ORIGIN é incluído na lista de autorizações de chaves adequada. Por exemplo, se uma chave for gerada em hardware seguro, Tag::ORIGIN com o valor KeyOrigin::GENERATED será encontrado na lista hw_enforced das características da chave, enquanto uma chave que foi importada para hardware seguro tem o valor KeyOrigin::IMPORTED.

Autenticação do usuário

As implementações do KeyMint seguro não implementam a autenticação do usuário, mas dependem de outros apps confiáveis que o fazem. Para conferir a interface implementada por esses apps, consulte a página 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 de 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 do usuário é necessária, embora o acesso à chave ainda seja restrito ao próprio app (e a todos os apps a que ele concede acesso).
  • Tag::AUTH_TIMEOUT é um valor numérico que especifica, em segundos, quanto tempo a autenticação do usuário precisa ser recente para autorizar o uso da chave. Os timeouts não são cruzados entre 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 é de aproximadamente 136 anos; presumivelmente, os dispositivos Android são reiniciados com mais frequência do que isso).

Exigir um dispositivo desbloqueado

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

O UNLOCKED_DEVICE_REQUIRED é aplicado 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.

Para isso, o Keystore "superencripta" todas as chaves UNLOCKED_DEVICE_REQUIRED antes de armazená-las no banco de dados. Quando possível, ele protege as chaves de superencriptação (chaves super) enquanto o dispositivo está bloqueado, de modo que elas só podem ser recuperadas com o desbloqueio 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. Esta é uma chave AES-256-GCM. Ele criptografa chaves UNLOCKED_DEVICE_REQUIRED importadas ou geradas enquanto o dispositivo está desbloqueado para o usuário.
  • A superchave assimétrica UnlockedDeviceRequired. Este é um par de chaves ECDH P-521. Ele criptografa chaves UNLOCKED_DEVICE_REQUIRED importadas ou geradas enquanto o dispositivo está bloqueado para o usuário. As chaves criptografadas com essa chave assimétrica são criptografadas novamente com a chave simétrica no primeiro uso, o que só pode ocorrer enquanto o dispositivo está desbloqueado.

O keystore gera essas superchaves no momento da criação do usuário e as armazena no banco de dados, criptografadas pela senha sintética do usuário. Isso permite que eles sejam recuperados usando PIN, padrão ou senha equivalente.

O Keystore também armazena essas superchaves em cache na memória, permitindo que ele opere em chaves UNLOCKED_DEVICE_REQUIRED. No entanto, ele tenta armazenar em cache as partes secretas dessas chaves somente enquanto o dispositivo está desbloqueado para o usuário. Quando o dispositivo é bloqueado para o usuário, o Keystore anula 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 em cache. Isso faz com que as chaves super sejam recuperadas 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 fazer com que as superchaves sejam recuperáveis por qualquer um dos 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 KeyMint como uma chave vinculada a biometria que exige que a autenticação biométrica tenha sido bem-sucedida nos últimos 15 segundos e zere as cópias de 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 ativado, o Keystore vai manter as superchaves em cache no texto simples. Nesse caso, a segurança criptográfica para chaves UNLOCKED_DEVICE_REQUIRED não é fornecida. Os usuários podem evitar esse substituto menos seguro se não ativarem 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 desbloqueio equivalente a PIN, padrão ou senha, ele descriptografa a cópia dessas chaves armazenada no banco de dados. Caso contrário, ele verifica se salvou uma cópia dessas chaves criptografadas com uma chave vinculada a biometria e, se sim, tenta descriptografá-la. Isso só vai funcionar se o usuário tiver feito a autenticação com um biometria de classe 3 nos últimos 15 segundos, aplicada pelo KeyMint (não pelo Keystore).

Vinculação de cliente

A vinculação do cliente, a associação de uma chave a um app de 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 a 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 a apps.

Vencimento

O keystore oferece suporte à restrição do uso de chaves por data. O início de validade e a expiração da chave 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 em se a chave está sendo usada para "originar" um novo texto criptografado/assinatura/etc. ou para "usar" um texto criptografado/assinatura/etc. existente. Observe que 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 não estiverem presentes, será presumido que a chave em questão sempre poderá ser usada para descriptografar/verificar mensagens.

Como o tempo do relógio é fornecido pelo mundo não seguro, as tags relacionadas à expiração estão na lista aplicada pelo software.

Vinculação de raiz de confiança

O keystore exige que as chaves sejam vinculadas a uma raiz de confiança, que é uma bitstring fornecida ao hardware seguro KeyMint durante a inicialização, de preferência pelo bootloader. Essa string de bits é criptograficamente vinculada 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 de sistema diferente ou se o estado de bloqueio for alterado, nenhuma das chaves protegidas por KeyMint criadas pelo sistema anterior será utilizável, 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 a chaves aplicados pelo software, tornando impossível que um sistema operacional instalado por um invasor use chaves KeyMint.

Redefiniçã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, o HAL do KeyMint fornece uma interface para permitir que o Keystore forneça entropia adicional, que é misturada nos números aleatórios gerados.

Use um gerador de números aleatórios de hardware como a fonte de semente principal. 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.