Keystore (Android): o que é, arquitetura e princípios de funcionamento

Autor: IT Sectr Publicado: 2026-03-14 Tempo de leitura: 10 min

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 KeyStore que isola chaves criptográficas do espaço do usuário Android
  • As chaves são geradas dentro do TEE ou Secure Element e nunca deixam o ambiente seguro em texto simples
  • Android 9+ adiciona KeyGenParameterSpec.Builder com parâmetros: purpose, digest, padding, userAuthenticationRequired
  • A proteção biométrica de chaves requer confirmação do usuário via BiometricPrompt antes de cada operação
  • Keymaster HAL é uma camada de abstração de hardware que implementa operações criptográficas no TEE ou Secure Element

O que é Android Keystore?

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.

Arquitetura do KeyStore no Android

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.

Diferença do Java KeyStore

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.

Como funciona o Android Keystore?

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.

Processo de geração de chave

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.

kotlin
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()
}

Assinatura e verificação

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.

kotlin
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
}

Tipos de armazenamento KeyStore

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.

KeyStore de software (apenas software)

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).

KeyMaster de hardware (TEE/Secure Element)

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.

TipoLocal de armazenamentoNível de proteçãoDisponível desde API
SoftwareArquivo /data/misc/keystoreMédio (AES-256)API 1+
Keymaster 3TEE (TrustZone)AltoAPI 23+
Keymaster 4TEE + Secure I/OMuito altoAPI 28+
StrongBoxSecure Element de hardwareMáximoAPI 28+, opcional

Trabalhando com a API KeyStore

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.

Criação e carregamento do KeyStore

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).

kotlin
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)
}

Verificação do tipo de armazenamento

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).

Algoritmos e segurança

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.

Algoritmos suportados

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.

Proteção contra comprometimento

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

Qual a diferença entre Android Keystore e Java KeyStore?

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.

Posso importar uma chave existente para o Android Keystore?

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.

Como verificar se um dispositivo suporta KeyStore de hardware?

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().

O que acontece com as chaves quando o aplicativo é desinstalado?

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.

Como o KeyStore protege contra ataques de depuração?

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

  • Android Keystore é um provedor criptográfico JCA com isolamento de chaves por hardware via TEE ou Secure Element
  • As chaves são geradas dentro do TrustZone e nunca deixam o ambiente seguro em texto simples
  • KeyGenParameterSpec define os parâmetros da chave: purpose, digest, padding, userAuthenticationRequired, keyValidity
  • Keymaster HAL implementa três níveis: software, TEE (Keymaster 3/4) e StrongBox (Secure Element de hardware)
  • A proteção biométrica de chaves é fornecida via setUserAuthenticationRequired e BiometricPrompt com CryptoObject
  • Key Attestation (API 28+) permite verificação no servidor de que a chave foi criada em ambiente de hardware
  • Use o Android Keystore para armazenar chaves privadas para assinatura, criptografia e autenticação em aplicativos Android

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.

Discutir o projeto

Leia também