KeyStore (Android): Key Concepts, API, and How the Cryptographic Storage Works

Author: IT Sectr Published: 2026-03-14 Reading time: 10 min

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

  • Android KeyStore is a JCA provider for key storage with TEE, StrongBox, and biometric protection support
  • KeyGenParameterSpec defines the algorithm, purpose, digest, padding, and biometrics when creating a key
  • Keymaster HAL implements hardware cryptographic operations at Software, TEE, and StrongBox levels
  • Key Attestation (API 28+) allows the server to verify that the key was created in a hardware-backed Android KeyStore environment
  • Key alias is a string by which the application accesses the key in the Keystore; one alias corresponds to one key

What is KeyStore in Android?

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

Evolution of Android KeyStore

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.

Architecture and Components

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.

How Does KeyStore Work as a Cryptographic Provider?

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.

Provider Registration

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.

KeyStore Methods and Their Specifics

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.

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

Supported Algorithms and Key Types

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.

Asymmetric Algorithms

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.

Symmetric Algorithms

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.

AlgorithmKeymasterPurposeAPI
RSAKM 1.0+Signing, Encryption18+
ECKM 1.0+ECDSA, ECDH18+
AESKM 2.0+Symmetric Encryption23+
HMACKM 2.0+Authentication Code23+
ChaCha20KM 3.0+Stream Encryption31+
X25519/Ed25519KM 3.0+Key Exchange31+

Key Types and Serialization

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.

Key Generation and Usage Examples

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.

Generating an AES Key for Encryption

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

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

Signing with Biometric Protection

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.

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

KeyStore and Device Security

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 (Android 8.1+)

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.

Key Invalidation on Biometric Change

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

What is the difference between Android KeyStore and Bouncy Castle KeyStore?

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.

Can I use one key for both encryption and signing?

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.

How can I tell if a key is hardware-backed in Android KeyStore?

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.

What happens when all biometric templates are removed?

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.

Does Android KeyStore support key backup?

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

  • Android KeyStore — JCA provider for hardware-isolated key storage via Keymaster HAL in TEE/StrongBox
  • KeyGenParameterSpec configures algorithm, size, purposes, digest, biometrics, and time-based key restrictions
  • RSA (KM 1.0+), EC (KM 1.0+), AES (KM 2.0+), ChaCha20 (KM 3.0+) — supported algorithms with different Keymaster levels
  • Key Attestation (API 28+) allows the server side to verify the hardware origin of the key
  • Biometric key protection via setUserAuthenticationRequired + BiometricPrompt with CryptoObject
  • Key invalidation on biometric change prevents unauthorized use of added fingerprints
  • Use Android KeyStore for generating and storing cryptographic keys with hardware protection in Android applications

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.

Discuss the project

Read also