Esta página contém informações sobre os recursos criptográficos do Android Keystore, conforme fornecidos pela implementação do KeyMint (ou Keymaster) subjacente.
Primitivas criptográficas
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 com a parte da chave pública do par de chaves. O certificado também pode conter informações sobre os metadados da chave e o estado do dispositivo, tudo assinado por uma chave que volta 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)
O Keystore e o KeyMint não processam operações de chave pública para chaves assimétricas.
Os elementos do protocolo, como finalidade, modo e padding, bem como restrições de controle de acesso, são especificados quando as chaves são geradas ou importadas e ficam permanentemente vinculados a elas, garantindo que não possam ser usadas de nenhuma outra forma.
Além da lista acima, há mais um serviço fornecido pelas implementações do KeyMint (antes Keymaster), mas que não é exposto como uma API: geração de números aleatórios. Usado internamente para geração de chaves, vetores de inicialização (IVs), padding aleatório e outros elementos de protocolos seguros que exigem aleatoriedade.
Primitivos necessárias
Todas as implementações do KeyMint oferecem:
- RSA
- Suporte para chaves de 2048, 3072 e 4096 bits
- Suporte para o expoente público F4 (2^16+1)
- Modos de padding para assinatura RSA:
- RSASSA-PSS (
PaddingMode::RSA_PSS
) - RSASSA-PKCS1-v1_5 (
PaddingMode::RSA_PKCS1_1_5_SIGN
)
- RSASSA-PSS (
- Modos de resumo para assinatura RSA:
- SHA-256
- Modos de padding para criptografia/descriptografia RSA:
- Sem padding
- RSAES-OAEP (
PaddingMode::RSA_OAEP
) - RSAES-PKCS1-v1_5 (
PaddingMode::RSA_PKCS1_1_5_ENCRYPT
)
- ECDSA
- Há suporte para chaves de 224, 256, 384 e 521 bits usando as curvas NIST P-224, P-256, P-384 e P-521, respectivamente.
- Modos de resumo para ECDSA:
- Nenhum resumo (descontinuado, será removido no futuro)
- SHA-256
- AES
- Chaves de 128 e 256 bits são aceitas
- CBC, CTR, ECB e GCM. A implementação do GCM não permite o uso de tags menores que 96 bits ou comprimentos de nonce diferentes de 96 bits.
- Os modos de padding
PaddingMode::NONE
ePaddingMode::PKCS7
são compatíveis com os modos CBC e ECB. Sem padding, a criptografia no modo CBC ou ECB falha se a entrada não for um múltiplo do tamanho do bloco.
- HMAC SHA-256, com qualquer tamanho de chave até pelo menos 32 bytes.
O SHA1 e os outros membros da família SHA2 (SHA-224, SHA384 e SHA512) são altamente recomendados para implementações do KeyMint. O keystore os fornece em software se a implementação de hardware do KeyMint não os fornecer.
Algumas primitivas também são recomendadas para interoperabilidade com outros sistemas:
- Tamanhos menores de chaves RSA
- Expoentes públicos arbitrários para RSA
Controle de acesso à chave
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. Por isso, é fundamental que o Keystore aplique controles de acesso.
Os controles de acesso são definidos como uma "lista de autorização" de pares 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, isso é especificado na interface HAL do KeyMint. Quando uma chave é criada, o autor da chamada especifica uma lista de autorização. A implementação do KeyMint que embasa o Keystore modifica a lista para especificar algumas informações adicionais, como se a chave tem proteção contra rollback, e retorna uma lista de autorizações "final", codificada no blob de chave retornado. Qualquer tentativa de usar a chave para uma operação criptográfica falha se a lista de autorização final for modificada.
Para o Keymaster 2 e versões anteriores, o conjunto de tags possíveis
é definido na enumeração
keymaster_authorization_tag_t
e
é permanentemente fixo (embora possa ser estendido).
Os nomes foram prefixados com KM_TAG
. Os quatro bits principais dos IDs de tag são usados para indicar o tipo.
O Keymaster 3 mudou o prefixo KM_TAG
para
Tag::
.
Os tipos possíveis incluem:
ENUM
:muitos valores de tags são definidos em
enumerações. Por exemplo, os valores possíveis de TAG::PURPOSE
são definidos na enumeração keymaster_purpose_t
.
ENUM_REP
:igual a ENUM
, exceto que a tag pode ser repetida em uma lista de autorização. A repetição indica vários valores autorizados. Por exemplo, uma chave de criptografia provavelmente tem KeyPurpose::ENCRYPT
e KeyPurpose::DECRYPT
.
Quando o KeyMint cria uma chave, o autor da chamada especifica uma lista de autorizações para ela. Essa lista é modificada pelo Keystore e pelo KeyMint para adicionar restrições extras, e a implementação do KeyMint subjacente codifica a lista de autorização final no keyblob retornado. A lista de autorizações codificada é criptograficamente vinculada 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 hardware x software
Nem todas as implementações de hardware seguro têm os mesmos recursos. Para oferecer suporte a várias abordagens, o Keymaster distingue entre o controle de acesso seguro e não seguro do mundo, 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 da 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 a 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 Confirmação 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 de 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, expresso como uma ou mais
entradas de autorização com a tag Tag::PURPOSE
, que define como elas
podem ser usadas. As finalidades estã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 Keymaster oferece suporte à exportação apenas de chaves públicas, no formato X.509, e à 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, o Tag::ORIGIN
é incluído na lista de autorização de chave apropriada. Por exemplo, se uma chave
foi gerada em hardware seguro, Tag::ORIGIN
com
valor KeyOrigin::GENERATED
será encontrado na
lista hw_enforced
das características da chave, enquanto uma chave
importada para hardware
seguro terá o valor KeyOrigin::IMPORTED
.
Autenticação do usuário
Implementações seguras do KeyMint não implementam autenticação do usuário, mas dependem de outros apps confiáveis que fazem isso. Para a interface implementada por esses apps, 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 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 um dos valores for fornecido em um token de autenticação segura.
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,
será necessário fazer a autenticação a cada uso da chave.
Tag::NO_AUTHENTICATION_REQUIRED
indica que não é necessária autenticação do usuário, mas o acesso à chave ainda é restrito ao app proprietário (e a qualquer app a que ele conceda 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 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 são aproximadamente 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
é 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 "supercriptografa" todas as chaves
UNLOCKED_DEVICE_REQUIRED
antes de armazená-las no banco de dados
e, quando possível, protege as chaves de supercriptografia (superchaves) enquanto o
dispositivo está bloqueado de forma que elas só possam ser recuperadas com um
desbloqueio bem-sucedido do dispositivo. O termo "supercriptografia" é usado porque essa camada de criptografia é aplicada além de outra camada 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. Esse é 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, que só pode ocorrer enquanto o dispositivo estiver 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 um PIN, padrão ou senha equivalente.
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 de 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 faz com que as superchaves só possam ser recuperadas pela cópia criptografada no banco de dados, que só pode ser descriptografada por um 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 permitir que as superchaves sejam recuperadas por qualquer uma das biometrias de classe 3 registradas pelo usuário (geralmente impressão digital), como alternativa ao PIN, padrão ou senha equivalente. Para 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 a biometria que exige autenticação biométrica para ter sido bem-sucedida nos últimos 15 segundos e zera as cópias de texto simples de todas essas chaves.
- Se o usuário tiver uma biometria de classe 1 ("conveniência"), classe 2 ("fraca")
ou um agente de confiança de desbloqueio ativo, o Keystore manterá as
superchaves armazenadas em cache em texto simples. Nesse caso, a segurança criptográfica para chaves
UNLOCKED_DEVICE_REQUIRED
não é fornecida. Os usuários podem evitar esse fallback menos seguro não ativando esses métodos de desbloqueio. Os métodos de desbloqueio mais comuns 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 descriptografar. Isso só vai funcionar se o usuário tiver se autenticado com uma biometria de classe 3 nos últimos 15 segundos, conforme exigido pelo KeyMint (nã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 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 está disponível para apps.
Vencimento
O keystore permite restringir o uso de chaves por data. O início da validade e o vencimento da chave podem ser associados a uma chave, e o Keymaster 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" se baseia em se a chave está 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 poderá ser usada para descriptografar/verificar mensagens.
Como o tempo real é fornecido pelo mundo não seguro, as tags relacionadas à expiração estão na lista de imposição de 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 bootloader. Essa string de bits é vinculada criptograficamente a todas as chaves gerenciadas pelo KeyMint.
A raiz de confiança consiste na 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 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 impostos por software, impossibilitando que um sistema operacional instalado por um invasor use chaves KeyMint.
Chaves independentes
Alguns hardwares seguros do KeyMint podem armazenar o material da chave internamente
e retornar identificadores em vez de material de chave criptografado. Ou pode haver outros casos em que as chaves não podem ser usadas até que outro componente do sistema não seguro ou seguro esteja disponível. A HAL do KeyMint permite que o autor da chamada
solicite que uma chave seja "independente" usando a tag TAG::STANDALONE
.
Isso significa que nenhum recurso além do blob e do sistema KeyMint em execução
é necessário. As tags associadas a uma chave podem ser inspecionadas para verificar se uma
chave é independente. No momento, apenas dois valores estão definidos:
KeyBlobUsageRequirements::STANDALONE
KeyBlobUsageRequirements::REQUIRES_FILE_SYSTEM
Esse recurso não está disponível para apps.
Velocidade
Quando ele é criado, a velocidade máxima de uso pode ser especificada com TAG::MIN_SECONDS_BETWEEN_OPS
.
As implementações do TrustZone se recusam a realizar operações criptográficas
com essa chave se uma operação foi realizada menos
de TAG::MIN_SECONDS_BETWEEN_OPS
segundos antes.
A abordagem simples para implementar limites de velocidade é uma tabela de IDs de chave e carimbos de data/hora de último uso. Essa tabela tem um tamanho limitado, mas acomoda pelo menos 16 entradas. Se a tabela estiver cheia e nenhuma entrada puder ser atualizada ou descartada, as implementações de hardware seguro vão "falhar com segurança", preferindo recusar todas as operações de chave com limite de velocidade até que uma das entradas expire. É aceitável que todas as entradas expirem após a reinicialização.
As chaves também podem ser limitadas a n usos por inicialização com
TAG::MAX_USES_PER_BOOT
. Isso também exige uma tabela de rastreamento,
que acomoda pelo menos quatro chaves e também tem falha segura. Os apps não podem criar chaves limitadas por inicialização. Esse recurso
não é exposto pelo Keystore e é reservado para operações do sistema.
Esse recurso não está disponível para apps.
Nova geração de números aleatórios
Como o hardware seguro gera números aleatórios para material de chave e vetores de inicialização (IVs), e como os geradores de números aleatórios de hardware nem sempre são totalmente confiáveis, a HAL KeyMint fornece uma interface para permitir que o cliente 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 inicialização fornecidos pela API externa não podem ser a única fonte de aleatoriedade usada para geração de números. Além disso, a operação de combinação usada precisa garantir que a saída aleatória seja imprevisível se qualquer uma das fontes de sementes for imprevisível.