KeyStore (Android) is an implementation of the Java Cryptography Architecture (JCA) cryptographic provider integrated into Android for secure key storage with hardware isolation capabilities. Since Android 4.3 (API 18), KeyStore supports hardware keys through Keymaster HAL, and starting with Android 9 (API 28), StrongBox Keymaster for keys in a dedicated Secure Element. According to Android Security Documentation, the “AndroidKeyStore” provider replaces standard Bouncy Castle or OpenSSL KeyStore, providing system-level protection against unauthorized key extraction.
Key Takeaways
KeyStore in Android is not a separate application or file, but a cryptographic provider implementing the java.security.KeyStore interface. It provides a unified API for storing and using private keys, symmetric keys, and trusted CA certificates. The provider is registered under the name “AndroidKeyStore” and is accessible via the standard KeyStore.getInstance().
Before Android 4.3, cryptographic operations were performed through Bouncy Castle. Android 4.3 introduced Keymaster HAL 1.0, enabling TEE usage on ARM TrustZone. Android 6.0 (API 23) added Keymaster 2.0 with hardware-backed fingerprint authentication. Android 9 (API 28) introduced Keymaster 4.0 and StrongBox Keymaster for a dedicated Secure Element.
Each version of Keymaster adds new capabilities and improves key isolation. Modern devices (2022+) must support Keymaster 4.0 for Google Mobile Services certification, guaranteeing TEE availability for all Android applications.
Android KeyStore consists of three layers: Java API (KeyStore, KeyPairGenerator), system process keystore (C++, runs as a system service), and Keymaster HAL (library in TEE or Secure Element). The application calls the API, the keystore service routes the request to Keymaster, and the operation is performed in the secure environment.
All private keys are stored in the TEE and cannot be read from user space. Even the system keystore service does not have access to raw keys — only to handles pointing to keys inside Keymaster.
Android KeyStore implements the standard JCA service provider interface. When an application calls Cipher.getInstance(“RSA/ECB/PKCS1Padding”, “AndroidKeyStore”), the Android Security Provider delegates the operation to Keymaster through the chain: Java → JNI → keystore service → Keymaster HAL.
The AndroidKeyStore provider is automatically registered when the process starts. Its priority is higher than that of Bouncy Castle or Conscrypt. Therefore, when calling KeyStore.getInstance() without specifying a provider, AndroidKeyStore is returned in most cases. For explicit invocation, use KeyStore.getInstance(“AndroidKeyStore”).
Each Android application has an isolated container in KeyStore. Applications with the same UID (shared userId) may share access to certain keys, but the standard setup guarantees that application A cannot read the keys of application B.
load(null) — KeyStore initialization. The parameter is always null for AndroidKeyStore. setEntry — saves a key with specified KeyProtection (purposes, digest, padding). getEntry — retrieves KeyStore.PrivateKeyEntry, SecretKeyEntry, or TrustedCertificateEntry. containsAlias — checks if a key exists. deleteEntry — permanently deletes a key.
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()
}
}
Android KeyStore supports a broad set of cryptographic algorithms, varying depending on the Keymaster HAL version on the device. A developer can get the list of supported algorithms through KeyGenParameterSpec.Builder when attempting generation — incompatible parameters throw InvalidAlgorithmParameterException.
RSA (1024–4096 bits) — for signing (PKCS1, PSS with SHA-1/SHA-256/SHA-384/SHA-512) and encryption (OAEP with SHA-1/SHA-256). EC (P-224, P-256, P-384, P-521) — for ECDSA signing and ECDH key agreement. X25519 and Ed25519 — since Android 12 (API 31) for modern cryptographic protocols.
For asymmetric keys, always generate inside Keymaster, NEVER import private keys. Imported private keys are not hardware-protected — they are stored in the software layer and are vulnerable if the app process is compromised.
AES (128, 256 bits) — for symmetric encryption in CBC, CTR, GCM modes. HMAC (SHA-1, SHA-256, SHA-512) — for message authentication. ChaCha20 (Android 12+) — for high-performance stream encryption with Poly1305 authentication.
| Algorithm | Keymaster | Purpose | API |
|---|---|---|---|
| RSA | KM 1.0+ | Signing, Encryption | 18+ |
| EC | KM 1.0+ | ECDSA, ECDH | 18+ |
| AES | KM 2.0+ | Symmetric Encryption | 23+ |
| HMAC | KM 2.0+ | Authentication Code | 23+ |
| ChaCha20 | KM 3.0+ | Stream Encryption | 31+ |
| X25519/Ed25519 | KM 3.0+ | Key Exchange | 31+ |
KeyStore.PrivateKeyEntry — contains a private key (non-exportable) and a certificate chain. KeyStore.SecretKeyEntry — for symmetric keys. KeyStore.TrustedCertificateEntry — for trusted CA certificates. Public keys are exportable via keyStore.getCertificate(alias).publicKey.
Let’s look at a complete scenario: generating an AES key for data encryption and generating an EC key for signing with biometric protection. Both keys are created inside Android KeyStore with hardware support.
An AES key is created via KeyGenerator with KeyGenParameterSpec. Parameters: PURPOSE_ENCRYPT + PURPOSE_DECRYPT, BLOCK_MODE_GCM (recommended mode with authentication), ENCRYPTION_PADDING_NONE (no padding needed for 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)
}
An EC key with userAuthenticationRequired=true requires user authentication before each signing operation. BiometricPrompt with CryptoObject containing the Signature object is used for this purpose. After successful biometric verification, Keymaster permits the operation.
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()
}
Android KeyStore provides hardware-level security guarantees that software-based KeyStores (JKS, BKS) cannot offer. Keys are protected at the SoC level, and even full control over the Android user space does not allow extracting the private key.
Key Attestation is a mechanism that allows an application (and server) to verify the environment in which a key was created. Android Keystore signs a certificate containing a list of key characteristics: algorithm, size, purposes, hardware-backed (True/False), origin (GENERATED, IMPORTED). The server verifies the certificate chain up to the Google root certificate.
This is critical for financial applications: the server can require that the key was created in a hardware environment (Hardware-Backed = True) and reject keys created in software Keystore. Key Attestation prevents attacks where an attacker replaces the Keystore with an emulator.
setInvalidatedByBiometricEnrollment(true) means the key will be automatically deleted by Keymaster when biometric templates are changed or removed. This protects against attacks where an attacker adds their fingerprint to an existing account. After a new fingerprint is added, old keys become inaccessible.
The failed biometric authentication attempt counter is also managed by Keymaster. After maxBiometricAttempt (configurable by manufacturer, typically 5), Keymaster blocks all operations with biometric keys for 30 seconds. After 10 failed attempts — until the device password (secret PIN) is entered.
Frequently Asked Questions
Bouncy Castle (BKS) is a software-based KeyStore that stores keys in a password-protected file. Android KeyStore uses hardware isolation TEE/StrongBox. BKS keys can be extracted with root access, Android KeyStore keys cannot. BKS is suitable for CA certificates, Android KeyStore is for private keys.
Yes, if you specify PURPOSE_ENCRYPT or PURPOSE_DECRYPT or PURPOSE_SIGN or PURPOSE_VERIFY at generation time. However, best practice is to create separate keys for different operations. This limits the damage if one key is compromised and follows the least privilege principle.
Use KeyStore.getKeyCharacteristics(alias), available via android.security.keystore. The method returns a set of flags: FLAG_HARDWARE — key in TEE, FLAG_SECURE_ELEMENT — key in StrongBox. If no flags are present, the key is software-only.
All keys created with setInvalidatedByBiometricEnrollment(true) will be automatically invalidated by Keymaster. When attempting to use them, the application will receive KeyPermanentlyInvalidatedException. Data encrypted with these keys will be permanently lost.
Hardware keys (in TEE/StrongBox) do not support backup — they are tied to a specific device. Software-backed keys can be included in Google Drive backup. To transfer data between devices, encrypt data on the server and decrypt on the new device.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also