Android Keystore é um mecanismo do sistema Android para armazenar com segurança chaves criptográficas em isolamento de hardware. O sistema utiliza Trusted Execution Environment (TEE) em dispositivos com ARM TrustZone ou um Secure Element dedicado para proteger chaves no nível do chip. De acordo com Android Open Source Project, o Keystore suporta os algoritmos RSA, EC, AES e HMAC com geração de chaves diretamente no ambiente seguro.
Principais conclusões
Android Keystore é um provedor criptográfico implementado no Android desde a API 1 (Android 1.0), mas o suporte completo a hardware apareceu com o Android 4.3 (API 18). O Keystore resolve o problema de armazenamento seguro de chaves privadas de modo que mesmo que o sistema operacional seja comprometido, um invasor não possa extrair chaves em texto simples.
A arquitetura do Android Keystore consiste em três camadas: a API da aplicação (java.security.KeyStore), o serviço do sistema (keystore daemon) e o nível de hardware (Keymaster HAL). A aplicação acessa através da API padrão Java Cryptography Architecture (JCA), e o serviço do sistema roteia as requisições para o Keymaster executando no TEE.
Todas as operações criptográficas com chaves (assinatura, descriptografia) são realizadas dentro do TEE ou Secure Element. As chaves nunca deixam o ambiente seguro — a aplicação recebe apenas um handle (apelido) para referenciar a chave. Esta é uma diferença fundamental dos KeyStores de software, onde as chaves são potencialmente acessíveis na memória do processo.
O JKS (Java KeyStore) padrão ou BKS (Bouncy Castle) armazenam chaves em arquivos protegidos por senha. O Android Keystore armazena chaves em isolamento de hardware, onde são protegidas até mesmo do usuário root. O JKS é vulnerável ao acesso direto ao sistema de arquivos; o Android Keystore não.
Outra diferença: no Android Keystore, as chaves têm parâmetros de uso estritos (purpose — apenas sign/verify/encrypt/decrypt) especificados no momento da geração. Eles não podem ser alterados posteriormente, o que impede o uso indevido da chave.
Ao criar uma nova chave, a aplicação chama KeyPairGenerator ou KeyGenerator com KeyGenParameterSpec, que contém todos os parâmetros da chave futura. O sistema passa a requisição para o Keymaster HAL, que gera a chave dentro do TEE e retorna um handle.
O método KeyGenParameterSpec.Builder aceita parâmetros obrigatórios: nome da chave no Keystore, propósito (PURPOSE_SIGN, PURPOSE_ENCRYPT), algoritmo (RSA, EC, AES). Adicionalmente: digest (SHA-256), padding (PKCS7), userAuthenticationRequired (biometria), keyValidityStart/End (restrições de tempo).
Após definir os parâmetros, KeyPairGenerator.generateKeyPair() retorna um KeyPair, onde PrivateKey é um objeto que delega operações ao Keymaster. A chave pública pode ser extraída, a privada não. Ela existe apenas dentro do TEE.
import java.security.KeyPairGenerator
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyProperties
fun generateKey(alias: String) {
val spec = KeyGenParameterSpec.Builder(alias,
KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY
).setDigests(KeyProperties.DIGEST_SHA256)
.setSignaturePaddings(KeyProperties.SIGN_PADDING_RSA_PKCS1)
.setUserAuthenticationRequired(true)
.build()
val kpGen = KeyPairGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_RSA,
"AndroidKeyStore"
)
kpGen.initialize(spec)
kpGen.generateKeyPair()
}
Signature para ECDSA ou RSA-PSS é criada através da API padrão: Signature.getInstance(algorithm).initSign(privateKey). A operação de assinatura é executada no TEE: a aplicação passa dados, o Keymaster os assina em hardware e retorna a assinatura. A chave e os dados não se misturam na memória compartilhada.
Para proteção biométrica, o usuário deve ser autenticado via BiometricPrompt antes de assinar. Sem autenticação bem-sucedida, o Keymaster não executa a operação e retorna CryptoAuthenticationException.
import java.security.KeyStore
import java.security.Signature
import androidx.biometric.BiometricPrompt
fun signWithBiometric(alias: String) {
val ks = KeyStore.getInstance("AndroidKeyStore")
ks.load(null)
val entry = ks.getEntry(alias, null) as KeyStore.PrivateKeyEntry
val signature = Signature.getInstance("SHA256withRSA")
signature.initSign(entry.privateKey)
// BiometricPrompt com CryptoObject(signature) solicita FaceID/PIN
}
O Android suporta dois modos de armazenamento de chaves: software (em dispositivos sem TEE) e hardware (em dispositivos com TEE ou Secure Element). O modo depende das capacidades do SoC e da versão do Android.
Em dispositivos sem Trusted Execution Environment (anteriores ao Android 4.3 ou SoCs de baixo custo), as chaves são armazenadas criptografadas usando uma chave mestre derivada da senha da tela de bloqueio. Este modo é menos seguro — as chaves são acessíveis na memória do processo durante operações criptográficas.
O nível de proteção é baseado na criptografia do arquivo KeyStore usando AES-256-GCM. A chave de criptografia é gerada a partir da senha ou PIN do usuário via Scrypt (PBKDF2 com alto número de iterações).
Em dispositivos modernos, utiliza-se Keymaster 4.x no TEE (ARM TrustZone). As chaves são geradas, armazenadas e usadas exclusivamente dentro do TrustZone. Até o kernel Linux não tem acesso às chaves privadas — apenas o Keymaster HAL pode realizar operações.
Secure Element (por exemplo, eSE no Samsung Knox ou StrongBox no Google Pixel 3+) é um chip separado com seu próprio processador e memória. É certificado Common Criteria EAL 4+ e fornece o máximo nível de proteção, incluindo proteção contra violação física.
| Tipo | Local de armazenamento | Nível de proteção | Disponível desde API |
|---|---|---|---|
| Software | Arquivo /data/misc/keystore | Médio (AES-256) | API 1+ |
| Keymaster 3 | TEE (TrustZone) | Alto | API 23+ |
| Keymaster 4 | TEE + Secure I/O | Muito alto | API 28+ |
| StrongBox | Secure Element de hardware | Máximo | API 28+, opcional |
O Android Keystore está integrado na Java Cryptography Architecture (JCA). Para acessar o provedor, usa-se KeyStore.getInstance("AndroidKeyStore"). A API está disponível desde a API 18.
O método KeyStore.load(null) carrega o contêiner KeyStore da aplicação. Nenhuma senha é necessária — o Android usa o contexto da aplicação e seu UID para controle de acesso. Cada aplicação vê apenas suas próprias entradas, a menos que um UID compartilhado seja usado.
Os métodos setEntry e getEntry trabalham com KeyStore.PrivateKeyEntry, SecretKeyEntry ou TrustedCertificateEntry. O parâmetro ProtectionParameter é sempre null para Android Keystore (a proteção é implementada no nível do sistema).
import java.security.KeyStore
import java.security.cert.Certificate
import android.security.keystore.KeyProtection
fun storeSecretKey(alias: String, key: SecretKey) {
val ks = KeyStore.getInstance("AndroidKeyStore")
ks.load(null)
val prot = KeyProtection.Builder(
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
).setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.setUserAuthenticationRequired(true)
.build()
ks.setEntry(alias, KeyStore.SecretKeyEntry(key), prot)
}
Usando KeyCharacteristics, é possível determinar em qual ambiente a chave está armazenada: KeyStore de software, TEE ou StrongBox. O método getKeyCharacteristics() retorna um conjunto de flags: FLAG_HARDWARE (keymaster), FLAG_SECURE_ELEMENT (StrongBox), FLAG_TRUSTED_USER_PRESENCE_REQUIRED (biometria).
O Android Keystore suporta uma ampla gama de algoritmos criptográficos divididos em três categorias: assimétricos, simétricos e MAC. O suporte a algoritmos específicos depende da versão do Keymaster HAL.
RSA (1024–4096 bits) — para assinatura (PKCS1, PSS) e criptografia (OAEP, PKCS1). EC (P-224, P-256, P-384, P-521) — para assinatura ECDSA e acordo de chaves ECDH. AES (128, 256 bits) — para criptografia simétrica nos modos CBC, CTR, GCM. HMAC (SHA1, SHA256, SHA512) — para autenticação de mensagens.
Para cada chave, especifica-se setPurposes para restringir as operações possíveis. Uma chave RSA com PURPOSE_SIGN não pode ser usada para criptografia, mesmo que um invasor tenha acesso à API. Isso é a aplicação do uso de chave no nível de hardware.
Keymaster inclui um contador de tentativas frustradas de autenticação biométrica. Após um número especificado de falhas (configurável via setInvalidatedByBiometricEnrollment), a chave se torna indisponível e requer exclusão/regeneração. Quando todos os modelos biométricos são removidos, todas as chaves com userAuthenticationRequired=true são automaticamente invalidadas.
Key Attestation (Android 8.1+) também é suportado: a pedido da aplicação, o Keymaster assina um certificado com informações sobre as características da chave (hardware/software, algoritmo, propósitos). O servidor pode verificar este certificado para confirmar que a chave foi criada em um ambiente confiável.
Perguntas frequentes
Java KeyStore armazena chaves em um arquivo protegido por senha (JKS, BKS). O Android Keystore usa isolamento de hardware via TEE ou Secure Element. O Java KeyStore é vulnerável ao acesso root; o Android Keystore não, porque as chaves privadas nunca deixam o ambiente seguro.
Sim, via KeyStore.setEntry com KeyProtection. No entanto, a chave importada não terá proteção de hardware — será armazenada no Keystore de software, criptografada com uma chave mestre. Para máxima segurança, sempre gere chaves dentro do Keystore.
Use KeyChain.isBoundKeyAlgorithm ou verifique KeyCharacteristics após a geração da chave. A presença de FLAG_HARDWARE nas características significa que a chave foi criada no TEE. Você também pode verificar android.security.keystore.isHardwareBacked().
Quando o aplicativo é desinstalado, o Android remove todas as suas chaves do Keystore. Os dados são perdidos irreversivelmente. Na reinstalação, o aplicativo deve gerar novas chaves. O backup de chaves via TEE é arquiteturalmente impossível.
Em um dispositivo bloqueado, o Keymaster não realiza nenhuma operação. Chaves com userAuthenticationRequired=true exigem confirmação biométrica a cada vez. Mesmo com acesso root, um invasor não pode chamar o Keymaster diretamente — apenas através do serviço Android Keystore.
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