KeyStore (Android) é uma implementação do provedor criptográfico Java Cryptography Architecture (JCA) integrada ao Android para armazenamento seguro de chaves com capacidade de isolamento de hardware. Desde o Android 4.3 (API 18), o KeyStore suporta chaves de hardware através do Keymaster HAL e, a partir do Android 9 (API 28), o StrongBox Keymaster para chaves em um Secure Element dedicado. De acordo com a Documentação de Segurança do Android, o provedor “AndroidKeyStore” substitui o Bouncy Castle ou OpenSSL KeyStore padrão, fornecendo proteção em nível de sistema contra extração não autorizada de chaves.
Principais pontos
KeyStore no Android não é um aplicativo ou arquivo separado, mas um provedor criptográfico que implementa a interface java.security.KeyStore. Ele fornece uma API unificada para armazenar e usar chaves privadas, chaves simétricas e certificados de CA confiáveis. O provedor é registrado sob o nome “AndroidKeyStore” e é acessível através do KeyStore.getInstance() padrão.
Antes do Android 4.3, as operações criptográficas eram realizadas através do Bouncy Castle. O Android 4.3 introduziu o Keymaster HAL 1.0, permitindo o uso de TEE no ARM TrustZone. O Android 6.0 (API 23) adicionou o Keymaster 2.0 com autenticação biométrica por hardware. O Android 9 (API 28) apresentou o Keymaster 4.0 e o StrongBox Keymaster para um Secure Element dedicado.
Cada versão do Keymaster adiciona novos recursos e melhora o isolamento de chaves. Dispositivos modernos (2022+) devem suportar Keymaster 4.0 para certificação Google Mobile Services, garantindo a disponibilidade de TEE para todos os aplicativos Android.
O Android KeyStore consiste em três camadas: API Java (KeyStore, KeyPairGenerator), processo de sistema keystore (C++, executado como serviço do sistema) e Keymaster HAL (biblioteca em TEE ou Secure Element). O aplicativo chama a API, o serviço keystore roteia a solicitação para o Keymaster e a operação é executada no ambiente seguro.
Todas as chaves privadas são armazenadas no TEE e não podem ser lidas do espaço do usuário. Até mesmo o serviço de keystore do sistema não tem acesso às chaves brutas — apenas aos handles que apontam para as chaves dentro do Keymaster.
O Android KeyStore implementa a interface padrão de provedor de serviços JCA. Quando um aplicativo chama Cipher.getInstance(“RSA/ECB/PKCS1Padding”, “AndroidKeyStore”), o Provedor de Segurança do Android delega a operação ao Keymaster através da cadeia: Java → JNI → serviço keystore → Keymaster HAL.
O provedor AndroidKeyStore é registrado automaticamente quando o processo é iniciado. Sua prioridade é maior que a do Bouncy Castle ou Conscrypt. Portanto, ao chamar KeyStore.getInstance() sem especificar um provedor, o AndroidKeyStore é retornado na maioria dos casos. Para invocação explícita, use KeyStore.getInstance(“AndroidKeyStore”).
Cada aplicativo Android tem um contêiner isolado no KeyStore. Aplicativos com o mesmo UID (shared userId) podem ter acesso compartilhado a determinadas chaves, mas a configuração padrão garante que o aplicativo A não possa ler as chaves do aplicativo B.
load(null) — inicialização do KeyStore. O parâmetro é sempre null para AndroidKeyStore. setEntry — salva uma chave com KeyProtection especificada (propósitos, digest, padding). getEntry — recupera KeyStore.PrivateKeyEntry, SecretKeyEntry ou TrustedCertificateEntry. containsAlias — verifica se uma chave existe. deleteEntry — exclui uma chave permanentemente.
import java.security.KeyStore
import java.security.KeyPairGenerator
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyProperties
object KeyStoreManager {
private val keyStore by lazy {
KeyStore.getInstance("AndroidKeyStore").apply { load(null) }
}
fun createRsaKey(alias: String) {
val spec = KeyGenParameterSpec.Builder(alias,
KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY
).setKeySize(2048)
.setDigests(KeyProperties.DIGEST_SHA256)
.setSignaturePaddings(KeyProperties.SIGN_PADDING_RSA_PKCS1)
.build()
val kpg = KeyPairGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_RSA,
"AndroidKeyStore"
)
kpg.initialize(spec)
kpg.generateKeyPair()
}
}
O Android KeyStore suporta um amplo conjunto de algoritmos criptográficos, variando de acordo com a versão do Keymaster HAL no dispositivo. Um desenvolvedor pode obter a lista de algoritmos suportados através do KeyGenParameterSpec.Builder ao tentar a geração — parâmetros incompatíveis lançam InvalidAlgorithmParameterException.
RSA (1024–4096 bits) — para assinatura (PKCS1, PSS com SHA-1/SHA-256/SHA-384/SHA-512) e criptografia (OAEP com SHA-1/SHA-256). EC (P-224, P-256, P-384, P-521) — para assinatura ECDSA e acordo de chaves ECDH. X25519 e Ed25519 — desde o Android 12 (API 31) para protocolos criptográficos modernos.
Para chaves assimétricas, sempre gere dentro do Keymaster, NUNCA importe chaves privadas. Chaves privadas importadas não são protegidas por hardware — são armazenadas na camada de software e vulneráveis se o processo do aplicativo for comprometido.
AES (128, 256 bits) — para criptografia simétrica nos modos CBC, CTR, GCM. HMAC (SHA-1, SHA-256, SHA-512) — para autenticação de mensagens. ChaCha20 (Android 12+) — para criptografia de fluxo de alto desempenho com autenticação Poly1305.
| Algoritmo | Keymaster | Propósito | API |
|---|---|---|---|
| RSA | KM 1.0+ | Assinatura, Criptografia | 18+ |
| EC | KM 1.0+ | ECDSA, ECDH | 18+ |
| AES | KM 2.0+ | Criptografia simétrica | 23+ |
| HMAC | KM 2.0+ | Código de autenticação | 23+ |
| ChaCha20 | KM 3.0+ | Criptografia de fluxo | 31+ |
| X25519/Ed25519 | KM 3.0+ | Troca de chaves | 31+ |
KeyStore.PrivateKeyEntry — contém uma chave privada (não exportável) e uma cadeia de certificados. KeyStore.SecretKeyEntry — para chaves simétricas. KeyStore.TrustedCertificateEntry — para certificados de CA confiáveis. Chaves públicas podem ser exportadas através de keyStore.getCertificate(alias).publicKey.
Vamos examinar um cenário completo: gerar uma chave AES para criptografia de dados e gerar uma chave EC para assinatura com proteção biométrica. Ambas as chaves são criadas dentro do Android KeyStore com suporte de hardware.
Uma chave AES é criada através do KeyGenerator com KeyGenParameterSpec. Parâmetros: PURPOSE_ENCRYPT + PURPOSE_DECRYPT, BLOCK_MODE_GCM (modo recomendado com autenticação), ENCRYPTION_PADDING_NONE (nenhum padding necessário para GCM).
import javax.crypto.KeyGenerator
import javax.crypto.Cipher
import javax.crypto.spec.GCMParameterSpec
fun generateAndEncrypt(alias: String, plainText: ByteArray): ByteArray {
val spec = KeyGenParameterSpec.Builder(alias,
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
).setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.setKeySize(256)
.build()
val kg = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
kg.initialize(spec)
kg.generateKey()
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
cipher.init(Cipher.ENCRYPT_MODE, getKeyFromStore(alias))
return cipher.doFinal(plainText)
}
Uma chave EC com userAuthenticationRequired=true requer autenticação do usuário antes de cada operação de assinatura. Para isso, é usado o BiometricPrompt com CryptoObject contendo o objeto Signature. Após a verificação biométrica bem-sucedida, o Keymaster permite a operação.
fun createBiometricSignKey(alias: String) {
val spec = KeyGenParameterSpec.Builder(alias,
KeyProperties.PURPOSE_SIGN
).setAlgorithmParameterSpec(
ECGenParameterSpec("secp256r1")
).setDigests(KeyProperties.DIGEST_SHA256)
.setUserAuthenticationRequired(true)
.setInvalidatedByBiometricEnrollment(true)
.build()
val kpg = KeyPairGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_EC,
"AndroidKeyStore"
)
kpg.initialize(spec)
kpg.generateKeyPair()
}
O Android KeyStore fornece garantias de segurança em nível de hardware que os KeyStore baseados em software (JKS, BKS) não podem oferecer. As chaves são protegidas no nível do SoC, e mesmo o controle total sobre o espaço do usuário do Android não permite extrair a chave privada.
Key Attestation é um mecanismo que permite que um aplicativo (e servidor) verifique o ambiente no qual uma chave foi criada. O Android Keystore assina um certificado contendo uma lista de características da chave: algoritmo, tamanho, propósitos, suportado por hardware (True/False), origem (GENERATED, IMPORTED). O servidor verifica a cadeia de certificados até o certificado raiz do Google.
Isso é fundamental para aplicativos financeiros: o servidor pode exigir que a chave tenha sido criada em um ambiente de hardware (Hardware-Backed = True) e rejeitar chaves criadas em Keystore de software. O Key Attestation previne ataques em que um invasor substitui o Keystore por um emulador.
setInvalidatedByBiometricEnrollment(true) significa que o Keymaster excluirá automaticamente a chave quando os templates biométricos forem alterados ou removidos. Isso protege contra ataques em que um invasor adiciona sua impressão digital a uma conta existente. Após adicionar uma nova impressão digital, as chaves antigas se tornam inacessíveis.
O contador de tentativas falhas de autenticação biométrica também é gerenciado pelo Keymaster. Após maxBiometricAttempt (configurável pelo fabricante, geralmente 5), o Keymaster bloqueia todas as operações com chaves biométricas por 30 segundos. Após 10 tentativas falhas — até que a senha do dispositivo (PIN secreto) seja inserida.
Perguntas frequentes
Bouncy Castle (BKS) é um KeyStore baseado em software que armazena chaves em um arquivo protegido por senha. O Android KeyStore usa isolamento de hardware TEE/StrongBox. As chaves BKS podem ser extraídas com acesso root, as chaves do Android KeyStore não. O BKS é adequado para certificados de CA, o Android KeyStore é para chaves privadas.
Sim, se você especificar PURPOSE_ENCRYPT ou PURPOSE_DECRYPT ou PURPOSE_SIGN ou PURPOSE_VERIFY no momento da geração. No entanto, a melhor prática é criar chaves separadas para diferentes operações. Isso limita o dano se uma chave for comprometida e segue o princípio do menor privilégio.
Use KeyStore.getKeyCharacteristics(alias), disponível através de android.security.keystore. O método retorna um conjunto de flags: FLAG_HARDWARE — chave no TEE, FLAG_SECURE_ELEMENT — chave no StrongBox. Se não houver flags, a chave é apenas software.
Todas as chaves criadas com setInvalidatedByBiometricEnrollment(true) serão invalidadas automaticamente pelo Keymaster. Ao tentar usá-las, o aplicativo receberá KeyPermanentlyInvalidatedException. Os dados criptografados com essas chaves serão perdidos permanentemente.
Chaves de hardware (em TEE/StrongBox) não suportam backup — elas estão vinculadas a um dispositivo específico. Chaves de software podem ser incluídas no backup do Google Drive. Para transferir dados entre dispositivos, criptografe os dados no servidor e descriptografe no novo dispositivo.
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