Zygote
Securitynerd

Keystore and hardware keys

Keystore lets an app use a key without ever holding it. The key lives in a TEE or a discrete secure chip, and attestation lets a remote server verify what kind of protection it actually has.

12 minAPI 1–37 · 17interactivequizverified 2026-10-27

The strongest encryption in the world is useless if the key is sitting in the same process as the data. Keystore's design premise is simple and strict: the key is never in your app's memory, and on most devices it is never in Android's memory either.

TL;DR#

  • is a system service that stores and uses keys. Apps ask for operations, not for key material.
  • The key blob is encrypted such that Keystore can store it but not use it or reveal it. The operations happen in a or, on some devices, a chip.
  • The hardware interface is , which replaced Keymaster in Android 12.
  • gives a remote server a signed statement about the key and the device's security state.
  • Keys can be bound to the user's authentication, so they are usable only after a recent unlock.

Mental model#

Think of a bank's safe-deposit service.

You do not take your valuables home with you. You give them to the bank, which puts them in a vault you cannot enter. When you need to use them, you go to the counter, prove who you are, and ask the bank to perform an operation. The bank does the operation inside the vault and hands you the result.

Keystore is the counter. The vault is the TEE. The proof of identity is your app's UID and, for auth-bound keys, a recent biometric or credential check.

Where the analogy breaks#

A bank holds your valuables; Keystore may never have seen the key in the clear at all. The key can be generated inside the vault and never leave it, which is a stronger property than custody. And a bank can be robbed; the threat model for the TEE assumes an attacker with code execution in Android and tries to remain safe against it.

The big picture#

Loading diagram…
Text description of this diagram

The security onion, with keys and secrets as the innermost ring. Outside it are the app sandbox, permissions, the kernel, verified boot and the hardware root of trust. Its description notes that this ring makes stolen storage useless without the credential and the chip, but cannot protect data from a user who unlocks the device for an attacker. Keystore is the mechanism that makes the innermost ring not depend on the outer ones succeeding.

Deep dive#

The components#

Four pieces, each in a different privilege domain:

  1. AndroidKeyStore provider — the Java API an app calls.
  2. The keystore daemon — a system service (keystore2) that owns key blobs and enforces access control. It is written in Rust since Android 12.
  3. The KeyMint HAL — the interface to the secure environment, implementing IKeyMintDevice.aidl.
  4. The KeyMint trusted app — the code inside the TEE that actually performs cryptographic operations and validates access-control conditions.

The key insight is at step 3: the HAL implementation is not supposed to perform sensitive operations in user space, or even in kernel space.1 The operation happens in the secure environment.

Key descriptors and access control#

A key is identified by a descriptor that combines a domain with an identity:

  • APP — the app's alias plus the caller's UID. The normal case.
  • KEY_ID — an internal numeric id.
  • GRANT — app-to-app delegation by UID.
  • BLOB — system-only; the client stores the keyblob, used by vold for file encryption.
  • SELINUX — system-only sharing by numeric SELinux label.

Each key carries authorizations that the TEE enforces before any operation: the purpose (encrypt, decrypt, sign, verify), the padding and digest, the key size, and whether authentication is required.

Authentication binding#

An auth-bound key is usable only if the user has authenticated recently. The mechanism involves three components: LockSettingsService (which knows the credential), Gatekeeper (which verifies it), and the biometric stack (which verifies a biometric and produces a token).

The token has a time limit and is signed by the secure environment. When an app requests an operation on an auth-bound key, it supplies the token, and the TEE checks it. That is why a banking app can require "fingerprint within the last 30 seconds" without the app having to enforce anything itself.

Attestation#

Key attestation is a signed certificate chain that describes the key and the device:2

  • The key's algorithm, size, purposes and authorizations.
  • Whether it is hardware-backed, and whether it is in a TEE or StrongBox.
  • The device's verified boot state and lock state.
  • The system and vendor patch levels.
  • An ID attestation extension (from Android 8) that can include the serial number, product name and IMEI/MEID.

A remote server can verify the chain against Google's root and decide whether to trust the device. That is how a banking app can distinguish a genuine device with a locked bootloader from an emulator or a tampered one — without trusting the app, which might itself be running on a compromised device.

StrongBox versus TEE#

A TEE is a secure execution mode on the main SoC, with its own memory that Android cannot read. It is the default for hardware-backed keys on most devices.

StrongBox is a discrete security chip, separate from the SoC. It offers stronger isolation — a compromise of the SoC does not necessarily compromise the chip — at the cost of performance and silicon area.

An app can request StrongBox for a key, and it must handle the case where the device does not have one: setIsStrongBoxBacked(true) on a device without StrongBox fails, and the app should fall back to the TEE.

Biometrics#

The biometric stack is adjacent to Keystore and often confused with it.

BiometricPrompt is the API. Behind it, BiometricService coordinates the available modalities — fingerprint, face, iris — each implemented by a vendor HAL. The important security property is that a biometric match does not unlock a key directly. It produces an auth token, and that token satisfies the auth-bound key's condition.

That indirection is what allows the biometric to be spoofed-resistant in the way the platform measures: the biometric security classification (Class 3, formerly Strongunverified(the Class 1/2/3 naming replaced Strong/Weak in Android 11; the exact introduction is not confirmed here)) is about the sensor and the matching algorithm, and the token is the interface between that classification and the key policy.

What Keystore cannot protect#

  • A rooted device with a compromised TEE. The threat model assumes the TEE is intact. If the vendor's TEE implementation is broken, the key protections are broken.
  • A user who unlocks for an attacker. Auth-bound keys are bound to authentication, not to intent.
  • A malicious app with the same UID. Keystore's identity is the UID; an app that can run code in your UID can use your keys.
  • Screenshot-based exfiltration. Keystore protects keys, not the data they decrypt.

How it evolved#

Security and privacy changes7 releases
APIVersionWhat changed
184.3 Jelly Bean
  • App Ops (hidden) introduced for permission control
236.0 Marshmallow
  • requestPermissions() and the runtime permission flow
289 Pie
  • Foreground service permission
3011
  • One-time permissions
3112
  • Bluetooth scan/connect permissions
3313 Tiramisu
  • POST_NOTIFICATIONS runtime permission
3717 Cinnamon Bun
  • ACCESS_LOCAL_NETWORK runtime permission for local network access

The trajectory: a software keystore, then a hardware-backed one (Keymaster), then a Rust rewrite and a new HAL (KeyMint, Android 12), then attestation becoming the interface that remote services actually use. Each step moved more of the guarantee into hardware and more of the verification into cryptography.

Under the hood#

Curiosity corner#

  • keystore2 is one of Android's largest Rust components. It is a security-critical daemon parsing untrusted input, which is exactly the profile Rust is chosen for.
  • SELinux IDs for Keystore are partitioned by partition. System, system-ext, product and vendor each get a numeric range, so a vendor key cannot collide with a platform key.
  • A key can be created with an expiry date and a usage count. The authorizations are enforced by the TEE, so a key can be made unusable after N operations or after a date, without any app logic.

Try it#

Look at the keystore service

adb shell service list | grep keystore adb shell dumpsys android.security.keystore2 | head -30 adb shell getprop ro.hardware.keystore

The ro.hardware.keystore property names the KeyMint implementation on the device, which is a rough indication of the secure environment behind it.

Check yourself#

Check yourself

1 / 12

Which layer enforces the app sandbox?

0 answered · 0 correct

Sources#

Sources

Every version number, API level, class name and date on this page is traced to one of these. Pages are re-verified against them; last_verified above says when.

  1. docsKeystoresource.android.comaccessed 2026-10-27↩
  2. docsKeystore key attestationsource.android.comaccessed 2026-10-27↩
  3. docsKeystore featuressource.android.comaccessed 2026-10-27↩
  4. docsAuthentication (Gatekeeper, biometrics)source.android.comaccessed 2026-10-27↩
  5. docsBiometric securitysource.android.comaccessed 2026-10-27↩
  6. docsMeasure biometric securitysource.android.comaccessed 2026-10-27↩
  7. docsDICE (Device Identifier Composition Engine)source.android.comaccessed 2026-10-27↩
  8. docsHardware abstraction layers (HALs)source.android.comaccessed 2026-10-27↩