Esta página contém informações sobre os recursos criptográficos do Keystore no Android 6.0 e superior.
Primitivas criptográficas
O Keystore fornece as seguintes categorias de operações:
- Geração de chave
- Importação e exportação de chaves assimétricas (sem encapsulamento de chaves)
- Importação de chaves simétricas brutas (sem encapsulamento de chaves)
- Criptografia e descriptografia assimétricas com modos de preenchimento apropriados
- Assinatura e verificação assimétrica com digestão e modos de preenchimento apropriados
- Criptografia e descriptografia simétricas em modos apropriados, incluindo um modo AEAD
- Geração e verificação de códigos de autenticação de mensagens simétricas
Os 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 ficam permanentemente vinculadas à chave, garantindo que a chave não possa ser usada de nenhuma outra forma.
Além da lista acima, existe mais um serviço que as implementações do Keymaster fornecem, mas que não é exposto como API: a geração de números aleatórios. Isso é usado internamente para geração de chaves, vetores de inicialização (IVs), preenchimento aleatório e outros elementos de protocolos seguros que exigem aleatoriedade.
Primitivas necessárias
Todas as implementações do Keymaster fornecem:
- RSA
- Suporte a chaves de 2048, 3072 e 4096 bits
- Suporte para 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:
- Não preenchido
- 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 (obsoleto, será removido no futuro)
- SHA-256
- AES
- Chaves de 128 e 256 bits são suportadas
- CBC , CTR, BCE 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.
- Modos de preenchimento
PaddingMode::NONE
ePaddingMode::PKCS7
são suportados para os modos CBC e ECB. Sem preenchimento, a criptografia no modo CBC ou ECB falhará 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.
SHA1 e os outros membros da família SHA2 (SHA-224, SHA384 e SHA512) são fortemente recomendados para implementações Keymaster. O Keystore os fornece em software se a implementação do Keymaster em hardware não os fornece.
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 chave
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 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 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 documentação da tag . Quando uma chave é criada, o chamador especifica uma lista de autorizações. A implementação do Keymaster subjacente ao Keystore modifica a lista para especificar algumas informações adicionais, como se a chave tem proteção contra reversão e retorna uma lista de autorização "final", codificada no blob de chave retornado. Qualquer tentativa de usar a chave para qualquer operação criptográfica falhará se a lista de autorização final for modificada.
Para Keymaster 2 e 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 primeiros bits dos IDs das tags são usados para indicar o tipo.
Keymaster 3 alterou o prefixo KM_TAG
para Tag::
.
Os tipos possíveis incluem:
ENUM
: Os valores de muitas tags são definidos em enumerações. Por exemplo, os valores possíveis de TAG::PURPOSE
são definidos em enum keymaster_purpose_t
.
ENUM_REP
: O mesmo que 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
.
UINT
: inteiros sem sinal de 32 bits. Exemplo: TAG::KEY_SIZE
UINT_REP
: O mesmo que UINT
, exceto que a tag pode ser repetida em uma lista de autorizações. A repetição indica vários valores autorizados.
ULONG
: inteiros sem sinal de 64 bits. Exemplo: TAG::RSA_PUBLIC_EXPONENT
ULONG_REP
: O mesmo que ULONG
, exceto que a tag pode ser repetida em uma lista de autorização. 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 "falsa" se a tag não estiver presente e "true" se estiver presente. Exemplo: TAG::ROLLBACK_RESISTANT
BIGNUM
: Inteiros de comprimento arbitrário, expressos como uma matriz de bytes em ordem big-endian. Exemplo: TAG::RSA_PUBLIC_EXPONENT
BYTES
: Uma sequência de bytes. Exemplo: TAG::ROOT_OF_TRUST
Aplicação de hardware versus software
Nem todas as implementações de hardware seguro contêm os mesmos recursos. Para suportar uma variedade de abordagens, a Keymaster distingue entre aplicação de controle de acesso mundial seguro e não seguro, ou aplicação de hardware e software, respectivamente.
Todas as implementações:
- Imponha a correspondência exata (não a aplicação) de todas as autorizações. As listas de autorização em blobs de chaves correspondem exatamente às autorizações devolvidas durante a geração de chaves, incluindo a encomenda. Qualquer incompatibilidade causa um diagnóstico de erro.
- Declare as autorizações cujos valores semânticos são impostos.
O mecanismo de API para declarar autorizações impostas por hardware está na estrutura keymaster_key_characteristics_t
. Ele divide a lista de autorização 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 pode impor.
Além disso, o Keystore implementa a aplicação baseada em software de todas as autorizações, sejam elas aplicadas pelo hardware seguro ou não.
Por exemplo, considere uma implementação baseada em TrustZone que não oferece suporte à expiração de chave. Uma chave com data de validade ainda pode ser criada. A lista de autorização dessa chave incluirá a tag TAG::ORIGINATION_EXPIRE_DATETIME
com a data de validade. Uma solicitação ao Keystore para obter as principais características encontrará essa tag na lista sw_enforced
e o hardware seguro não imporá o requisito de expiração. No entanto, as tentativas de usar a chave após a expiração serão rejeitadas pelo Keystore.
Se o dispositivo for atualizado com hardware seguro que suporte a expiração, uma solicitação de características da chave encontrará TAG::ORIGINATION_EXPIRE_DATETIME
na lista hw_enforced
e as tentativas de usar a chave após a expiração falharão mesmo se o armazenamento de chaves for de alguma forma subvertido ou ignorado .
Para obter mais informações sobre como determinar se as chaves 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 usando 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, o que significa que vários valores podem ser associados a uma única chave e o valor a ser usado é especificado no momento da operação.
Propósito
As chaves possuem um conjunto de propósitos associado, expresso como uma ou mais entradas de autorização com a tag TAG::PURPOSE
, que define como elas podem ser utilizadas. Os propósitos são:
-
KeyPurpose::ENCRYPT
-
KeyPurpose::DECRYPT
-
KeyPurpose::SIGN
-
KeyPurpose::VERIFY
Qualquer chave pode ter qualquer subconjunto dessas finalidades. Observe que 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
Keymaster suporta 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 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 valor KeyOrigin::GENERATED
será encontrado na lista hw_enforced
das características da chave, enquanto uma chave que foi importada para hardware seguro terá o valor KeyOrigin::IMPORTED
.
Autenticação de usuário
As implementações do Secure Keymaster não implementam a autenticação do usuário, mas dependem de outros aplicativos confiáveis que o fazem. Para a interface que esses aplicativos implementam, consulte a página do Gatekeeper .
Os requisitos de autenticação do usuário são especificados por meio de 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
possui um valor numérico especificando o ID do usuário autorizado. Observe que este é o ID do usuário do Android (para multiusuário), não o UID do aplicativo, e é aplicado apenas por software não seguro. Se presente,TAG::ALL_USERS
não está presente. -
TAG::USER_SECURE_ID
possui um valor numérico de 64 bits que especifica o ID do usuário seguro que é 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 aplicativos executados como o(s) usuário(s) especificado(s) porTAG::USER_ID
. -
TAG::AUTH_TIMEOUT
é um valor numérico que especifica, em segundos, quão atualizada a autenticação do usuário precisa ser para autorizar o uso da chave. Isso se aplica apenas a operações de chave privada/secreta. As operações de chave pública não requerem autenticação. Os tempos limite não cruzam as 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 equivale a aproximadamente 136 anos; presumivelmente, os dispositivos Android são reinicializados com mais frequência do que isso).
Vinculação do cliente
A ligação do cliente, a associação de uma chave com um aplicativo cliente específico, é feita por meio de um ID de cliente opcional e alguns dados opcionais do cliente ( 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 ligação do cliente não são retornados pelo Keymaster. O chamador precisa saber disso para usar a chave.
Este recurso não está exposto a aplicativos.
Expiração
O Keystore oferece suporte à restrição do uso de chaves por data. O início da 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 cifrado/assinatura/etc., ou para "usar" um texto cifrado/assinatura/etc existente. Observe que esta distinção não está exposta a aplicativos.
As 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 horário do relógio é fornecido pelo mundo não seguro, é improvável que as tags relacionadas à expiração estejam na lista imposta por hardware. A aplicação da expiração por hardware exigiria que o mundo seguro obtivesse de alguma forma tempo e dados confiáveis, por exemplo, por meio de um protocolo de resposta a desafios com um servidor de horário remoto confiável.
Raiz de ligação de confiança
O Keystore exige que as chaves estejam vinculadas a uma raiz de confiança, que é uma cadeia de bits fornecida ao hardware seguro do Keymaster durante a inicialização, de preferência pelo gerenciador de inicialização. Esta cadeia de bits é criptograficamente vinculada a cada chave gerenciada 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 que uma imagem de sistema diferente seja usada ou se o estado de bloqueio for alterado, então 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 que é assinado por essa chave é inicializado. O objetivo é aumentar o valor dos controles de acesso às chaves impostos por software, tornando impossível para um sistema operacional instalado por um invasor usar chaves Keymaster.
Chaves independentes
Alguns hardwares seguros Keymaster podem optar por armazenar material de 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 não seguro ou seguro do sistema mundial esteja disponível. O Keymaster HAL permite que o chamador solicite que uma chave seja "autônoma", por meio da tag TAG::STANDALONE
, o que significa que nenhum outro 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. Atualmente, apenas dois valores são definidos:
-
KeyBlobUsageRequirements::STANDALONE
-
KeyBlobUsageRequirements::REQUIRES_FILE_SYSTEM
Este recurso não está exposto a aplicativos.
Velocidade
Quando é 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 executada menos de TAG::MIN_SECONDS_BETWEEN_OPS
segundos antes.
A abordagem simples para implementar limites de velocidade é uma tabela de IDs principais e carimbos de data/hora do último uso. Esta tabela provavelmente terá tamanho limitado, mas acomoda pelo menos 16 entradas. No caso de a tabela estar cheia e nenhuma entrada poder ser atualizada ou descartada, as implementações de hardware seguras "à prova de falhas", preferindo recusar todas as operações de chave com velocidade limitada até que uma das entradas expire. É aceitável que todas as entradas expirem na 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 é à prova de falhas. Observe que os aplicativos não poderão criar chaves limitadas por inicialização. Esse recurso não é exposto por meio do Keystore e é reservado para operações do sistema.
Este recurso não está exposto a aplicativos.
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), e como os geradores de números aleatórios de hardware podem nem sempre ser totalmente confiáveis, o Keymaster HAL fornece uma interface para permitir que o cliente forneça entropia adicional que será misturada no aleatório números gerados.
Use um gerador de números aleatórios de hardware como fonte primária de propagação. Os dados iniciais fornecidos por meio da 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 mistura utilizada precisa garantir que a saída aleatória seja imprevisível se qualquer uma das fontes de sementes for imprevisível.
Esse recurso não é exposto aos aplicativos, mas é usado pela estrutura, que fornece regularmente entropia adicional, recuperada de uma instância Java SecureRandom, para o hardware seguro.