Esta página contém informações sobre os recursos criptográficos do Keystore no Android 6.0 e versões mais recentes.
Primitivos criptográficos
O keystore fornece as seguintes categorias de operações:
- Geração de chaves
- Importação e exportação de chaves assimétricas (sem chave encapsulada)
- Importação de chaves simétricas brutas (sem chaves encapsuladas)
- Criptografia e descriptografia assimétricas com modos de preenchimento adequados
- Assinatura e verificação assimétricas com modos de preenchimento e resumo adequados
- Criptografia e descriptografia simétricas em modos apropriados, incluindo um modo AEAD
- Geração e verificação de códigos de autenticação de mensagem simétrica
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 ela não possa ser usada de nenhuma outra forma.
Além da lista acima, há mais um serviço que as implementações do Keymaster oferecem, mas que não é exposto como uma API: geração de números aleatórios. Isso é usado internamente para a geração de chaves, vetores de inicialização (IVs), preenchimento aleatório e outros elementos de protocolos seguros que exigem aleatoriedade.
Primitivos necessários
Todas as implementações do Keymaster oferecem:
- RSA
- Suporte a chaves de 2048, 3072 e 4096 bits
- Suporte para o expoente público F4 (2^16+1)
- Modos de preenchimento 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 preenchimento para criptografia/descriptografia RSA:
- Sem preenchimento
- RSAES-OAEP (
PaddingMode::RSA_OAEP
) - RSAES-PKCS1-v1_5 (
PaddingMode::RSA_PKCS1_1_5_ENCRYPT
)
- ECDSA
- Suporte a 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:
- Sem resumo (descontinuado, será removido no futuro)
- SHA-256
- AES
- Chaves de 128 e 256 bits são compatíveis
- 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 preenchimento
PaddingMode::NONE
ePaddingMode::PKCS7
são compatíveis com os modos CBC e ECB. Sem preenchimento, a criptografia 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 de até 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 Keymaster. O Keystore os fornece no software se a implementação do Keymaster de hardware não os fornecer.
Algumas primitivas também são recomendadas para interoperabilidade com outros sistemas:
- Tamanhos de chave menores para RSA
- Expoentes públicos arbitrários para RSA
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). Quando uma chave é criada, o autor da chamada especifica uma lista de autorizações. A implementação do Keymaster no keystore modifica a lista para especificar algumas informações adicionais, como se a chave tem proteção de reversão, e retorna uma lista de autorização "final", codificada no blob de chaves retornado. Qualquer tentativa de usar a chave para qualquer operação criptográfica falhará se a lista de autorizações 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
é fixado permanentemente (embora possa ser estendido).
Os nomes foram prefixados com KM_TAG
. Os quatro bits
superiores 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 no tipo enumerado keymaster_purpose_t
.
ENUM_REP
:igual a ENUM
,
exceto que a tag pode ser repetida em uma lista de autorizações. A repetição
indica vários valores autorizados. Por exemplo, uma chave de criptografia
provavelmente tem KeyPurpose::ENCRYPT
e
KeyPurpose::DECRYPT
.
UINT
:números inteiros não assinados de 32 bits. Exemplo:
TAG::KEY_SIZE
UINT_REP
:igual a UINT
,
exceto que a tag pode ser repetida em uma lista de autorizações. A repetição
indica vários valores autorizados.
ULONG
:números inteiros não assinados de 64 bits. Exemplo:
TAG::RSA_PUBLIC_EXPONENT
ULONG_REP
:igual a ULONG
,
exceto que a tag pode ser repetida em uma lista de autorizações. A repetição
indica vários valores autorizados.
DATE
:valores de data/hora, expressos em
milissegundos desde 1º de janeiro de 1970.
Exemplo: TAG::PRIVKEY_EXPIRE_DATETIME
BOOL
:verdadeiro ou falso. Uma tag do tipo
BOOL
é considerada "false" se não estiver presente e
"true" se estiver. Exemplo: TAG::ROLLBACK_RESISTANT
BIGNUM
:números inteiros de comprimento arbitrário,
expressos como uma matriz de bytes na ordem big-endian. Exemplo:
TAG::RSA_PUBLIC_EXPONENT
BYTES
:uma sequência de bytes. Exemplo:
TAG::ROOT_OF_TRUST
Aplicação de software versus hardware
Nem todas as implementações de hardware seguro contêm os mesmos recursos. Para oferecer suporte a várias abordagens, o Keymaster distingue entre a aplicação de controle de acesso segura e não segura, ou a aplicação de hardware e software, respectivamente.
Todas as implementações:
- Aplique a correspondência exata (não a aplicação) de todas as autorizações. As listas de autorizações em blobs de chaves correspondem exatamente às autorizações retornadas durante a geração de chaves, incluindo a ordem. Qualquer incompatibilidade causa um diagnóstico de erro.
- Declare as autorizações cujos valores semânticos são aplicados.
O mecanismo da API para declarar autorizações aplicadas por hardware está na
estrutura keymaster_key_characteristics_t
. Ele divide a
lista de autorizações em duas sublistas, hw_enforced
e
sw_enforced
. O hardware seguro é responsável por colocar os
valores apropriados em cada um, com base no que ele pode aplicar.
Além disso, o Keystore implementa a aplicação baseada em software de todas as autorizações, independentemente de serem aplicadas pelo hardware seguro ou não.
Por exemplo, considere uma implementação baseada na TrustZone que não oferece suporte à
expiração de chaves. Uma chave com uma data de validade ainda pode ser criada. A lista de autorizações dessa chave inclui a tag TAG::ORIGINATION_EXPIRE_DATETIME
com a data de validade. Uma
solicitação ao Keystore para as características da chave encontra essa tag na
lista sw_enforced
, e o hardware seguro não aplica o
requisito de expiração. No entanto, as tentativas de usar a chave após a expiração são
rejeitadas pelo Keystore.
Se o dispositivo for atualizado com hardware seguro que ofereça suporte
à expiração, uma solicitação de características de chaves vai encontrar
TAG::ORIGINATION_EXPIRE_DATETIME
na lista hw_enforced
e tentar usar a chave após a expiração, mesmo que o
keystore seja subvertido ou ignorado.
Para mais informações sobre como determinar se as chaves são protegidas 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
e TAG::DIGEST
.
TAG::PADDING
, TAG::DIGEST
e PaddingMode::BLOCK_MODE
são repetíveis, ou seja, vários valores podem ser associados a uma única chave, e o valor a ser usado é especificado no momento da operação.
Objetivo
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:
KeyPurpose::ENCRYPT
KeyPurpose::DECRYPT
KeyPurpose::SIGN
KeyPurpose::VERIFY
Qualquer chave pode ter qualquer subconjunto dessas finalidades. Algumas combinações criam problemas de segurança. Por exemplo, uma chave RSA que pode ser usada para criptografar e assinar permite que um invasor convença o sistema a descriptografar dados arbitrários para gerar assinaturas.
Importar e exportar
O Keymaster oferece suporte apenas à exportação de chaves públicas, no formato X.509, e à importação de:
- Pares de chaves públicas e privadas 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 Keymaster 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 qual usuário pode usar a chave:
TAG::ALL_USERS
indica que a chave pode ser usada por todos os usuários. Se presente,TAG::USER_ID
eTAG::USER_SECURE_ID
não estão presentes.TAG::USER_ID
tem um valor numérico que especifica o ID do usuário autorizado. Esse é o ID do usuário do Android (para vários usuários), não o UID do app, e é aplicado apenas por softwares não seguros. Se presente,TAG::ALL_USERS
não está presente.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.
NO_AUTHENTICATION_REQUIRED
indica que nenhuma autenticação do usuário é necessária, embora a chave ainda possa ser usada apenas por apps executados como os usuários especificados porTAG::USER_ID
.TAG::AUTH_TIMEOUT
é um valor numérico que especifica, em segundos, o quão recente a autenticação do usuário precisa ser para autorizar o uso da chave. Isso se aplica apenas a operações de chaves privadas/secretas. As operações de chave pública não exigem autenticação. Os tempos limite não são cruzados entre reinicializações. Após uma reinicialização, todas as chaves nunca são autenticadas. 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 reinicializados 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)
.
UNLOCKED_DEVICE_REQUIRED
é aplicado pelo Keystore, não pelo
Keymaster. 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 supercriptografia (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 Keymaster 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 P-521
ECDH. 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 chaves superchaves com ela, importa a chave AES-256-GCM para o Keymaster como uma chave vinculada a biometria que exige que a autenticação biométrica tenha sido bem-sucedida nos últimos 15 segundos e anula 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, 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 Keymaster (não pelo Keystore).
Vinculação do cliente
A vinculação do cliente, a associação de uma chave a um app de cliente
específico, é feita usando 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
Keymaster. 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 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" é 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, é improvável que as tags relacionadas à expiração estejam na lista aplicada pelo hardware. A aplicação de hardware da expiração exigiria que o mundo seguro de alguma forma recebe tempo e dados confiáveis, por exemplo, por meio de um protocolo de resposta de desafio com um servidor de tempo remoto confiável.
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 do Keymaster durante a inicialização, de preferência pelo bootloader. Essa string de bits é criptograficamente vinculada a todas as chaves gerenciadas pelo Keymaster.
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 Keymaster 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 à chave aplicados pelo software, tornando impossível que um sistema operacional instalado por um invasor use chaves Keymaster.
Chaves independentes
Alguns hardwares seguros do Keymaster 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 algum outro componente do sistema
do mundo não seguro ou seguro esteja disponível. O HAL do Keymaster permite que o autor da chamada
solicite que uma chave seja "independente" usando a tag TAG::STANDALONE
,
o que significa que nenhum recurso além do blob e do sistema Keymaster 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 são definidos:
KeyBlobUsageRequirements::STANDALONE
KeyBlobUsageRequirements::REQUIRES_FILE_SYSTEM
Esse recurso não é exposto a apps.
Velocidade
Quando ela é criada, 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 tiver sido realizada menos
de TAG::MIN_SECONDS_BETWEEN_OPS
segundos antes.
A abordagem simples para implementar limites de velocidade é uma tabela de IDs de chaves e carimbos de data/hora de uso. Essa tabela tem um tamanho limitado, mas pode acomodar pelo menos 16 entradas. Caso a tabela esteja cheia e nenhuma entrada possa ser atualizada ou descartada, as implementações de hardware seguras "fail safe", preferindo recusar todas as operações de chave limitadas por 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 requer uma tabela de rastreamento,
que acomoda pelo menos quatro chaves e também falha com segurança. 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 é exposto a apps.
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 Keymaster fornece uma interface para permitir que o cliente 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.
Esse recurso não é exposto a apps, mas é usado pelo framework, que regularmente fornece entropia adicional, extraída de uma instância do Java SecureRandom, para o hardware seguro.