MASTG-KNOW-0043: Android KeyStore
O Android KeyStore oferece um armazenamento de credenciais relativamente seguro. A partir do Android 4.3 (API nível 18), ele disponibiliza APIs públicas para armazenar e usar chaves privadas do aplicativo. Um app pode usar uma chave pública para criar um novo par de chaves pública/privada para criptografar segredos da aplicação e pode descriptografar esses segredos com a chave privada.
Você pode proteger chaves armazenadas no Android KeyStore com autenticação do usuário em um fluxo de confirmação de credenciais. As credenciais da tela de bloqueio do usuário (padrão, PIN, senha ou impressão digital) são usadas para autenticação.
Você pode usar chaves armazenadas em um de dois modos:
-
Os usuários são autorizados a usar chaves por um período limitado após a autenticação. Neste modo, todas as chaves podem ser utilizadas assim que o usuário desbloqueia o dispositivo. É possível personalizar o período de autorização para cada chave. Esta opção só pode ser usada se a tela de bloqueio segura estiver ativada. Se o usuário desativar a tela de bloqueio segura, todas as chaves armazenadas se tornarão permanentemente inválidas.
-
Os usuários são autorizados a usar uma operação criptográfica específica associada a uma chave. Neste modo, os usuários devem solicitar uma autorização separada para cada operação que envolva a chave. Atualmente, a autenticação por impressão digital é a única forma de solicitar tal autorização.
O nível de segurança proporcionado pelo Android KeyStore depende de sua implementação, que varia conforme o dispositivo. A maioria dos dispositivos modernos oferece uma implementação do KeyStore com suporte de hardware): as chaves são geradas e usadas em um Ambiente de Execução Confiável (TEE) ou em um Elemento Seguro (SE), e o sistema operacional não pode acessá-las diretamente. Isso significa que as próprias chaves de criptografia não podem ser facilmente recuperadas, mesmo em um dispositivo com root. Você pode verificar chaves com suporte de hardware com Key Attestation. É possível determinar se as chaves estão dentro do hardware seguro verificando o valor retornado pelo método isInsideSecureHardware, que faz parte da classe KeyInfo.
Observe que o KeyInfo relevante indica que chaves secretas e chaves HMAC são armazenadas de forma insegura em vários dispositivos, embora as chaves privadas estejam corretamente armazenadas no hardware seguro.
As chaves de uma implementação apenas de software são criptografadas com uma chave mestra de criptografia por usuário. Um invasor pode acessar todas as chaves armazenadas em dispositivos com root que possuem esta implementação na pasta /data/misc/keystore/. Como o PIN/senha da tela de bloqueio do usuário é usado para gerar a chave mestra, o Android KeyStore fica indisponível quando o dispositivo está bloqueado. Para maior segurança, o Android 9 (API nível 28) introduz a flag unlockedDeviceRequired. Ao passar true para o método setUnlockedDeviceRequired, o aplicativo impede que suas chaves armazenadas no AndroidKeystore sejam descriptografadas quando o dispositivo está bloqueado, exigindo que a tela seja desbloqueada antes de permitir a descriptografia.
Android KeyStore com suporte de hardware¶
O Android KeyStore com suporte de hardware oferece uma camada adicional ao conceito de segurança em profundidade para Android. A Camada de Abstração de Hardware do Keymaster (HAL) foi introduzida no Android 6 (API nível 23). Aplicativos podem verificar se a chave está armazenada dentro do hardware de segurança (verificando se KeyInfo.isInsideSecureHardware retorna true). Dispositivos com Android 9 (API nível 28) ou superior podem ter um módulo StrongBox Keymaster, uma implementação da HAL do Keymaster que reside em um módulo de segurança de hardware com sua própria CPU, armazenamento seguro, um gerador verdadeiro de números aleatórios e um mecanismo para resistir à violação de pacotes. Para usar este recurso, true deve ser passado para o método setIsStrongBoxBacked na classe KeyGenParameterSpec.Builder ou na classe KeyProtection.Builder ao gerar ou importar chaves usando o AndroidKeystore. Para garantir que o StrongBox seja usado durante a execução, verifique se isInsideSecureHardware retorna true e se o sistema não lança StrongBoxUnavailableException, que é lançada se o Keymaster do StrongBox não estiver disponível para o algoritmo e tamanho de chave associados a uma chave. A descrição dos recursos do keystore baseado em hardware pode ser encontrada nas páginas da AOSP.
A HAL do Keymaster é uma interface para componentes com suporte de hardware - Ambiente de Execução Confiável (TEE) ou Elemento Seguro (SE), que é usado pelo Android Keystore. Um exemplo de tal componente com suporte de hardware é o Titan M.