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.