Android Keystore é um provedor criptográfico que gera e armazena chaves de criptografia em um ambiente de execução isolado (TEE), inacessível até mesmo para o sistema operacional. De acordo com AOSP Security Documentation (2025), o Keystore é usado em mais de 80% dos aplicativos Android do top 100 do Google Play para proteger tokens e criptografar dados. Entender o Android Keystore é fundamental para o armazenamento seguro de chaves no Android.
Principais pontos
Android Keystore — um componente de sistema da plataforma Android que fornece uma API para gerar, armazenar e usar chaves criptográficas em um ambiente protegido. Ao contrário das bibliotecas criptográficas de software (Bouncy Castle, Conscrypt), o Keystore garante que as chaves privadas nunca deixem a área de execução isolada.
O Keystore apareceu pela primeira vez no Android 4.3 (API 18) como um provedor de software com suporte a RSA. A partir do Android 6.0 (API 23), o Keystore recebeu suporte de hardware através do Keymaster Hardware Abstraction Layer (HAL), que delega operações criptográficas ao Trusted Execution Environment (TEE) em dispositivos compatíveis. De acordo com o Android Compatibility Definition Document (2025), todos os dispositivos com Android 9+ devem suportar Keystore baseado em hardware via TEE ou StrongBox.
As chaves no Keystore são identificadas por um alias — uma string passada ao criar ou carregar uma chave. O Keystore não permite acesso ao material bruto da chave: os métodos getEncoded() retornam null para chaves criadas no Keystore. Esta é uma diferença fundamental das chaves de software — um invasor não pode extrair a chave privada mesmo com controle total do dispositivo.
O Keystore é integrado a outros mecanismos de segurança do Android: autenticação biométrica (BiometricPrompt), criptografia em nível de arquivo (File-Based Encryption) e funções de verificação SafetyNet / Play Integrity. As chaves podem ser configuradas para exclusão automática sob certas condições: quando o código de acesso é removido, quando uma nova impressão digital é adicionada ou no vencimento.
A arquitetura do Android Keystore inclui três níveis de implementação que diferem no grau de proteção de hardware. O nível depende das capacidades de hardware do dispositivo.
TEE (Trusted Execution Environment) — uma área isolada executando em paralelo com o sistema operacional principal no mesmo processador. O TEE usa a tecnologia ARM TrustZone, que divide o núcleo físico do processador em dois virtuais: Normal World (Android) e Secure World (TEE). O código no Secure World tem acesso à memória e periféricos inacessíveis do Normal World.
Quando um aplicativo chama uma operação criptográfica através do Keystore, a solicitação é passada através do Keymaster HAL para o TEE, onde a operação é executada por hardware. O resultado é retornado ao aplicativo, mas a chave privada permanece na memória protegida do TEE. TEE é certificado para conformidade com o GlobalPlatform TEE Protection Profile e é um requisito obrigatório para Android 9+ em dispositivos com processadores que suportam TrustZone.
O TEE suporta os algoritmos AES/GCM (128, 256 bits), RSA (2048, 4096 bits), EC (P-256, P-384, P-521) e HMAC-SHA256. O desempenho do TEE é menor que o da criptografia de software (20–40%), mas para operações típicas (assinatura JWT, descriptografia de chave de sessão), a latência não excede 10–50 ms.
StrongBox — um chip de segurança dedicado, fisicamente separado do processador principal. Ao contrário do TEE, que compartilha o tempo do processador com o Android, o StrongBox possui sua própria CPU, RAM, Gerador de Números Aleatórios Verdadeiros (TRNG) e armazenamento seguro (memória programável uma vez). StrongBox é certificado para Common Criteria EAL 4+ e Secure IC Protection Profile.
O StrongBox está disponível em dispositivos com Android 9+ desde que o chip correspondente esteja presente (por exemplo, Titan M no Google Pixel, Knox no Samsung Galaxy). O desenvolvedor ativa o StrongBox através da flag setIsStrongBoxBacked(true) no KeyGenParameterSpec. Se o suporte de hardware não estiver disponível, a flag é ignorada e o Keystore volta para o TEE.
Limitações do StrongBox: suporta um conjunto limitado de algoritmos (AES-256, EC P-256, HMAC-SHA256), fila de operações — no máximo uma por vez, número de operações — limitado pelos recursos do chip. O StrongBox não foi projetado para cenários de alta carga — use TEE para operações frequentes e StrongBox apenas para chaves críticas (chaves mestre de criptografia, chaves de assinatura).
O Keystore baseado em software é uma implementação de software usada em dispositivos sem suporte de hardware para TEE ou StrongBox. As chaves são armazenadas criptografadas no sistema de arquivos, mas a chave privada pode ser temporariamente descriptografada na RAM. Keystore de software é menos seguro — um invasor com acesso root pode interceptar a chave na memória.
A partir do Android 12 (API 31), o Google exige Keystore baseado em hardware para todos os novos dispositivos. Dispositivos com Android 9–11 podem ter Keystore de software em modelos de baixo custo. O desenvolvedor pode verificar o nível de proteção através de KeyStore.getKeyCharacteristics() — o atributo SECURITY_LEVEL_TRUSTED_ENVIRONMENT ou SECURITY_LEVEL_STRONGBOX confirma a proteção de hardware.
Android Keystore suporta uma ampla gama de algoritmos criptográficos, divididos em categorias dependendo do tipo de chave. A escolha do algoritmo afeta o desempenho, a compatibilidade e o nível de segurança.
AES (Advanced Encryption Standard) — criptografia simétrica para proteger dados no dispositivo. Modo recomendado: AES/GCM/NoPadding (256 bits). O GCM fornece criptografia autenticada (AEAD) — verificação de integridade dos dados criptografados. Tamanho do IV (Vetor de Inicialização): 12 bytes para GCM. Não use AES/ECB — ele não fornece proteção adequada.
RSA (Rivest–Shamir–Adleman) — criptografia assimétrica para proteger chaves de sessão e assinaturas digitais. Tamanho recomendado: 2048 ou 4096 bits. Modos: RSA/ECB/PKCS1Padding (criptografia) e RSA/ECB/PKCS1Sign (assinatura). RSA 1024 é considerado obsoleto e não é recomendado para novas aplicações (NIST SP 800-131A Rev. 2).
EC (Elliptic Curve) — criptografia assimétrica de curva elíptica para assinatura e troca de chaves. Curvas suportadas: secp256r1 (P-256, obrigatória), secp384r1 (P-384) e secp521r1 (P-521). EC oferece segurança comparável ao RSA com tamanho de chave significativamente menor. P-256 é recomendado para a maioria dos cenários: é suportado por todos os dispositivos e oferece nível de segurança de 128 bits.
HMAC (Hash-based Message Authentication Code) — autenticação simétrica de mensagens. Funções hash suportadas: SHA-256, SHA-384, SHA-512. HMAC é usado para verificar a integridade e autenticidade dos dados, por exemplo, para verificar requisições webhook ou verificar a integridade da configuração.
Todos os algoritmos podem ser vinculados à autenticação biométrica através de KeyGenParameterSpec.Builder.setUserAuthenticationRequired(true). No Android 11+, a flag setUserAuthenticationParameters() está disponível com um timeout (em segundos) durante o qual a chave está disponível após autenticação biométrica, sem solicitação repetida.
Vejamos exemplos práticos de trabalho com Android Keystore em Kotlin: gerar uma chave AES, criptografar dados e criar um par assimétrico para assinatura.
O exemplo cria uma chave AES/GCM de 256 bits com vínculo à autenticação biométrica. A chave não pode ser exportada via getEncoded().
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyProperties
import java.security.KeyStore
private val keyStore = KeyStore.getInstance("AndroidKeyStore").apply { load(null) }
fun generateAesKey(alias: String) {
val spec = KeyGenParameterSpec.Builder(
alias,
KeyProperties.PURPOSE_ENCRYPT or
KeyProperties.PURPOSE_DECRYPT
)
.setKeySize(256)
.setBlockModes(KeyProperties.KEY_BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.setUserAuthenticationRequired(true)
.setInvalidatedByBiometricEnrollment(true)
.build()
val generator = KeyGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_AES,
"AndroidKeyStore"
)
generator.init(spec)
generator.generateKey()
}
O exemplo criptografa dados usando uma chave do Android Keystore. Cipher obtém a chave por alias, inicializa a criptografia AES/GCM e retorna os dados criptografados junto com o IV.
fun encryptData(alias: String, plaintext: ByteArray): ByteArray {
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
val secretKey = keyStore.getKey(alias, null) as SecretKey
cipher.init(Cipher.ENCRYPT_MODE, secretKey)
val iv = cipher.getIV()
val encrypted = cipher.doFinal(plaintext)
// IV + dados criptografados
return iv + encrypted
}
fun decryptData(alias: String, ciphertextWithIv: ByteArray): ByteArray {
val iv = ciphertextWithIv.copyOfRange(0, 12)
val encrypted = ciphertextWithIv.copyOfRange(12, ciphertextWithIv.size)
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
val secretKey = keyStore.getKey(alias, null) as SecretKey
val spec = GCMParameterSpec(128, iv)
cipher.init(Cipher.DECRYPT_MODE, secretKey, spec)
return cipher.doFinal(encrypted)
}
O exemplo cria um par de chaves RSA-2048 no Keystore com vínculo StrongBox. A chave privada é usada para assinar, a chave pública pode ser exportada via getEncoded().
fun generateRsaKeyPair(alias: String) {
val spec = KeyGenParameterSpec.Builder(
alias,
KeyProperties.PURPOSE_SIGN or
KeyProperties.PURPOSE_VERIFY
)
.setKeySize(2048)
.setSignaturePaddings(
KeyProperties.SIGNATURE_PADDING_RSA_PKCS1
)
.setDigests(KeyProperties.DIGEST_SHA256)
.setIsStrongBoxBacked(true)
.build()
val pair = KeyPairGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_RSA,
"AndroidKeyStore"
).apply { init(spec) }
.generateKeyPair()
// A chave pública pode ser exportada
val publicKey = pair.public // X509EncodedKeySpec
}
O uso eficaz do Android Keystore requer seguir regras que garantam máxima proteção enquanto mantém o desempenho.
Use KeyGenParameterSpec com os parâmetros minimamente necessários: especifique apenas os propósitos, modos de bloco e preenchimentos realmente usados. Parâmetros redundantes (por exemplo, PURPOSE_ENCRYPT para uma chave usada apenas para assinatura) criam vetores de ataque desnecessários. O Android recomenda especificar explicitamente o digest para assinatura — SHA256 é o nível mínimo aceitável (SHA1 está obsoleto).
Vincule chaves à biometria para operações críticas: setUserAuthenticationRequired(true) garante que a chave só possa ser usada após autenticação biométrica. No Android 11+, use setUserAuthenticationParameters() com um timeout (recomendado 30–60 segundos) para evitar solicitar biometria para cada operação em uma mesma sessão. setInvalidatedByBiometricEnrollment(true) exclui automaticamente a chave quando uma nova impressão digital ou rosto é cadastrado — isso impede o acesso com dados biométricos antigos.
Verifique o nível de segurança na inicialização: use KeyStore.getKeyCharacteristics() para determinar SECURITY_LEVEL. Se o dispositivo suportar apenas Keystore de software (SECURITY_LEVEL_SOFTWARE), tome uma decisão: recusar a funcionalidade ou usar criptografia adicional (por exemplo, encapsulamento de chave via senha do usuário). Não confie no StrongBox se não for garantido — sempre especifique a flag setIsStrongBoxBacked(true) e verifique o resultado via getKeyCharacteristics.
Rotacione as chaves regularmente: as chaves criptográficas têm uma vida útil recomendada. NIST SP 800-57 recomenda alterar as chaves AES a cada 1–2 anos, pares RSA/EC a cada 2–3 anos. Implemente um mecanismo de rotação de chaves: verifique a data de criação da chave na inicialização do aplicativo (KeyGenParameterSpec.Builder.setKeyValidityStart/End) e gere uma nova chave quando expirar. Dados antigos criptografados com a chave antiga devem ser descriptografados e reciptografados com a nova.
Não use o Keystore para dados grandes: o Keystore foi projetado para armazenar chaves (algumas centenas de bytes), não para criptografar arquivos grandes. Para criptografia de dados, use o esquema: gere uma chave AES aleatória (DEK — Data Encryption Key), criptografe os dados com esta chave e criptografe o DEK com uma chave Keystore (KEK — Key Encryption Key). O Android EncryptedSharedPreferences usa exatamente este esquema: chave mestre no Keystore, dados — AES-256 GCM.
Perguntas frequentes
Não, o Android Keystore foi projetado para que a chave privada nunca saia do TEE ou StrongBox. O método getEncoded() retorna null para chaves criadas no Keystore. A chave só pode ser usada através de Cipher, Signature ou Mac API — o material bruto é inacessível.
TEE (TrustZone) — isolamento virtual no mesmo processador, usa compartilhamento de tempo. StrongBox — um chip separado com própria CPU e memória. StrongBox é mais seguro (Common Criteria EAL 4+), mas mais lento e suporta menos algoritmos. TEE é adequado para operações frequentes, StrongBox para chaves críticas.
Use KeyStore.getKeyCharacteristics() após gerar uma chave com a flag setIsStrongBoxBacked(true). O atributo SECURITY_LEVEL_STRONGBOX confirma o suporte de hardware. Se o dispositivo não suportar StrongBox, o Keystore volta para TEE sem erro — você deve verificar explicitamente o nível de segurança.
As chaves no Keystore são excluídas automaticamente quando o aplicativo é desinstalado do dispositivo. No Android 10+, as chaves podem persistir se o aplicativo tiver a flag allowBackup=true no manifesto, mas ficarão indisponíveis após reinstalação. É recomendado gerar as chaves novamente em uma instalação limpa.
Não, o Android Keystore está vinculado ao hardware de um dispositivo específico. Uma chave gerada no TEE de um dispositivo não pode ser transferida para outro. Para criptografia multiplataforma, use o esquema: Keystore protege a chave no dispositivo e as chaves de sessão são transmitidas através de uma API segura usando criptografia assimétrica.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também