[ Web Proxy ]
URL:
Viewing: https://source.android.com/docs/security/features/keystore/features [Back]  [Original]

Features  |  Android Open Source Project Skip to main content
Android Open Source Project [Android Open Source Project]

Features Stay organized with collections Save and categorize content based on your preferences.

This page contains information about the cryptographic features of Android Keystore, as provided by the underlying KeyMint (or Keymaster) implementation.

Cryptographic primitives

Keystore provides the following categories of operations:

Note: Keystore and KeyMint don't handle public key operations for asymmetric keys.

Protocol elements, such as purpose, mode, and padding, as well as access control constraints, are specified when keys are generated or imported and are permanently bound to the key, ensuring the key can't be used in any other way.

In addition to the list above, there is one more service that KeyMint (previously Keymaster) implementations provide, but which isn't exposed as an API: Random number generation. This is used internally for generation of keys, Initialization Vectors (IVs), random padding and other elements of secure protocols that require randomness.

Necessary primitives

All KeyMint implementations provide:

SHA1 and the other members of the SHA2 family (SHA-224, SHA384 and SHA512) are strongly recommended for KeyMint implementations. Keystore provides them in software if the hardware KeyMint implementation doesn't provide them.

Some primitives are also recommended for interoperability with other systems:

Key access control

Hardware-based keys that can never be extracted from the device don't provide much security if an attacker can use them at will (though they're more secure than keys which can be exfiltrated). Thus, it's crucial that Keystore enforce access controls.

Access controls are defined as an "authorization list" of tag/value pairs. Authorization tags are 32-bit integers and the values are a variety of types. Some tags can be repeated to specify multiple values. Whether a tag can be repeated is specified in the KeyMint HAL interface. When a key is created, the caller specifies an authorization list. The KeyMint implementation underlying Keystore modifies the list to specify some additional information, such as whether the key has rollback protection, and return a "final" authorization list, encoded into the returned key blob. Any attempt to use the key for any cryptographic operation fails if the final authorization list is modified.

For Keymaster 2 and earlier, the set of possible tags is defined in the enumeration keymaster_authorization_tag_t and is permanently fixed (though it can be extended). Names were prefixed with KM_TAG. The top four bits of tag IDs are used to indicate the type.

Keymaster 3 changed the KM_TAG prefix to Tag::.

Possible types include:

ENUM: Many tags' values are defined in enumerations. For example, the possible values of TAG::PURPOSE are defined in enum keymaster_purpose_t.

ENUM_REP: Same as ENUM, except that the tag can be repeated in an authorization list. Repetition indicates multiple authorized values. For example, an encryption key likely has KeyPurpose::ENCRYPT and KeyPurpose::DECRYPT.

When KeyMint creates a key, the caller specifies an authorization list for the key. This list is modified by Keystore and KeyMint to add extra constraints, and the underlying KeyMint implementation encodes the final authorization list into the returned keyblob. The encoded authorization list is cryptographically bound into the keyblob, so that any attempt to modify the authorization list (including ordering) results in an invalid keyblob that can't be used for cryptographic operations.

Hardware versus software enforcement

Not all secure hardware implementations contain the same features. To support a variety of approaches, Keymaster distinguishes between secure and non-secure world access control enforcement, or hardware and software enforcement, respectively.

This is exposed in the KeyMint API with the securityLevel field of the KeyCharacteristics type. The secure hardware is responsible for placing the authorizations in the KeyCharacteristics with the appropriate security level, based on what it can enforce. This information is also exposed in the attestation records for asymmetric keys: key characteristics for SecurityLevel::TRUSTED_ENVIRONMENT or SecurityLevel::STRONGBOX appear in the hardwareEnforced list, and characteristics for SecurityLevel::SOFTWARE or SecurityLevel::KEYSTORE appear in the softwareEnforced list.

For example, constraints on the date and time interval when a key can be used are typically not enforced by the secure environment, because it doesn't have trustworthy access to date and time information. As a result, authorizations like Tag::ORIGINATION_EXPIRE_DATETIME are enforced by Keystore in Android, and would have SecurityLevel::KEYSTORE.

For more information about determining whether keys and their authorizations are hardware backed, see Key attestation.

Cryptographic message construction authorizations

The following tags are used to define the cryptographic characteristics of operations using the associated key:

The following tags are repeatable, meaning that multiple values can be associated with a single key:

The value to be used is specified at operation time.

Purpose

Keys have an associated set of purposes, expressed as one or more authorization entries with the Tag::PURPOSE tag, which defines how they can be used. The purposes are defined in KeyPurpose.aidl.

Note that some combinations of purpose values create security problems. For example, an RSA key that can be used to both encrypt and to sign allows an attacker who can convince the system to decrypt arbitrary data to generate signatures.

Key import

Keymaster supports export of public keys only, in X.509 format, and import of:

To ensure that imported keys can be distinguished from securely generated keys, Tag::ORIGIN is included in the appropriate key authorization list. For example, if a key was generated in secure hardware, Tag::ORIGIN with value KeyOrigin::GENERATED is found in the hw_enforced list of the key characteristics, while a key that was imported into secure hardware has the value KeyOrigin::IMPORTED.

User authentication

Secure KeyMint implementations don't implement user authentication, but depend on other trusted apps that do. For the interface that these apps implement, see the Gatekeeper page.

User authentication requirements are specified via two sets of tags. The first set indicates which authentication methods allow use of the key:

The second set indicates whether and when the user needs to be authenticated. If neither of these tags is present, but Tag::USER_SECURE_ID is, authentication is required for every use of the key.

Require an unlocked device

Keys with Tag::UNLOCKED_DEVICE_REQUIRED are usable only while the device is unlocked. For the detailed semantics, see KeyProtection.Builder#setUnlockedDeviceRequired(boolean).

UNLOCKED_DEVICE_REQUIRED is enforced by Keystore, not by KeyMint. However, in Android 12 and higher, Keystore cryptographically protects UNLOCKED_DEVICE_REQUIRED keys while the device is locked to ensure that, in most cases, they cannot be used even if Keystore is compromised while the device is locked.

All cryptography and random number generation described in this section uses BoringSSL, except where the use of KeyMint is explicitly mentioned. All secrets are zeroized as soon as they are no longer needed.

UnlockedDeviceRequired super keys

To cryptographically protect UNLOCKED_DEVICE_REQUIRED keys, Keystore "superencrypts" them before storing them in its database. When possible, it protects the superencryption keys (super keys) while the device is locked in such a way that they can be recovered only by a successful device unlock. (The term "superencryption" is used because this layer of encryption is applied in addition to the layer of encryption that KeyMint already applies to all keys.)

Each user (including profiles) has two super keys associated with UNLOCKED_DEVICE_REQUIRED:

Generating and protecting the super keys

When a user is created, Keystore generates the user's UnlockedDeviceRequired super keys and stores them in its database, encrypted (indirectly) by the user's synthetic password:

  1. The system server derives the user's Keystore password from the user's synthetic password using an SP800‑108 KDF.
  2. The system server passes the user's Keystore password to Keystore.
  3. Keystore generates the user's super keys.
  4. For each of the user's super keys:
    1. Keystore generates a random salt.
    2. Keystore derives an AES‑256‑GCM key from the user's Keystore password and the salt using HKDF‑SHA256.
    3. Keystore encrypts the secret part of the super key using this AES‑256‑GCM key.
    4. Keystore stores the encrypted super key and its salt in its database. If it's an asymmetric key, the public half of the key is also stored unencrypted.

This procedure allows these super keys to be decrypted when the user's synthetic password is known, such as when the user's correct PIN, pattern, or password is entered.

Keystore also caches these super keys in memory, allowing it to operate on UNLOCKED_DEVICE_REQUIRED keys. However, it tries to cache the secret parts of these keys only while the device is unlocked for the user. When the device is locked for the user, Keystore zeroizes its cached copy of the secret parts of these super keys, if possible. Specifically, when the device is locked for the user, Keystore selects and applies one of three protection levels for the user's UnlockedDeviceRequired super keys:

When the device is unlocked for the user, Keystore recovers the user's UnlockedDeviceRequired super keys if possible. For PIN, pattern, or password equivalent unlock, it decrypts the copy of these keys that is stored in the database. Otherwise, it checks if it saved a copy of these keys encrypted with a biometric-bound key, and if so tries to decrypt that. This succeeds only if the user has successfully authenticated with a class 3 biometric within the last 15 seconds, enforced by KeyMint (not Keystore).

Storing keys while device is locked

Keystore allows users to import and generate UNLOCKED_DEVICE_REQUIRED keys while the device is locked. It uses a hybrid encryption scheme to ensure that they can be decrypted only when the device is later unlocked:

This feature makes it possible for apps to store data while the device is locked, such that it can be decrypted only while the device is unlocked. To do so, apps should follow these steps:

  1. Generate an AES‑256‑GCM key outside of Keystore.
  2. Encrypt data using the AES‑256‑GCM key.
  3. Import the AES‑256‑GCM key into Keystore with the setUnlockedDeviceRequired(true) key protection set.
  4. Zeroize the original copy of the key.

To decrypt the data while the device is unlocked, use the key that was imported into Keystore.

Client binding

Client binding, the association of a key with a particular client app, is done via an optional client ID and some optional client data (Tag::APPLICATION_ID and Tag::APPLICATION_DATA, respectively). Keystore treats these values as opaque blobs, only ensuring that the same blobs presented during key generation/import are presented for every use and are byte-for-byte identical. The client binding data isn't returned by KeyMint. The caller has to know it in order to use the key.

This feature isn't exposed to apps.

Expiration

Keystore supports restricting key usage by date. Key start of validity and key expirations can be associated with a key and Keymaster refuses to perform key operations if the current date/time is outside of the valid range. The key validity range is specified with the tags Tag::ACTIVE_DATETIME, Tag::ORIGINATION_EXPIRE_DATETIME, and Tag::USAGE_EXPIRE_DATETIME. The distinction between "origination" and "usage" is based on whether the key is being used to "originate" a new ciphertext/signature/etc., or to "use" an existing ciphertext/signature/etc. Note that this distinction isn't exposed to apps.

The Tag::ACTIVE_DATETIME, Tag::ORIGINATION_EXPIRE_DATETIME, and Tag::USAGE_EXPIRE_DATETIME tags are optional. If the tags are absent, it is assumed that the key in question can always be used to decrypt/verify messages.

Because wall-clock time is provided by the non-secure world, the expiration-related tags are in the software-enforced list.

Root of trust binding

Keystore requires keys to be bound to a root of trust, which is a bitstring provided to the KeyMint secure hardware during startup, preferably by the bootloader. This bitstring is cryptographically bound to every key managed by KeyMint.

The root of trust consists of the public key used to verify the signature on the boot image and the lock state of the device. If the public key is changed to allow a different system image to be used or if the lock state is changed, then none of the KeyMint-protected keys created by the previous system are usable, unless the previous root of trust is restored and a system that is signed by that key is booted. The goal is to increase the value of the software-enforced key access controls by making it impossible for an attacker-installed operating system to use KeyMint keys.

Standalone keys

Some KeyMint secure hardware can choose to store key material internally and return handles rather than encrypted key material. Or there might be other cases in which keys cannot be used until some other non-secure or secure world system component is available. The KeyMint HAL allows the caller to request that a key be "standalone," via the TAG::STANDALONE tag, meaning that no resources other than the blob and the running KeyMint system are required. The tags associated with a key can be inspected to see whether a key is standalone. At present, only two values are defined:

This feature isn't exposed to apps.

Velocity

When it's created, the maximum usage velocity can be specified with TAG::MIN_SECONDS_BETWEEN_OPS. TrustZone implementations refuse to perform cryptographic operations with that key if an operation was performed less than TAG::MIN_SECONDS_BETWEEN_OPS seconds earlier.

The simple approach to implementing velocity limits is a table of key IDs and last-use timestamps. This table is a limited size, but accommodates at least 16 entries. In the event that the table is full and no entries can be updated or discarded, secure hardware implementations "fail safe," preferring to refuse all velocity-limited key operations until one of the entries expires. It is acceptable for all entries to expire upon reboot.

Keys can also be limited to n uses per boot with TAG::MAX_USES_PER_BOOT. This also requires a tracking table, which accommodates at least four keys and also fails safe. Note that apps can't create per-boot limited keys. This feature isn't exposed through Keystore and is reserved for system operations.

This feature isn't exposed to apps.

Random number generator re-seeding

Because secure hardware generates random numbers for key material and initialization vectors (IVs), and because hardware random number generators might not always be fully trustworthy, the KeyMint HAL provides an interface to allow the client to provide additional entropy, which is mixed into the random numbers generated.

Use a hardware random-number generator as the primary seed source. The seed data provided through the external API can't be the sole source of randomness used for number generation. Further, the mixing operation used needs to ensure that the random output is unpredictable if any one of the seed sources is unpredictable.

Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.

Last updated 2026-07-16 UTC.

[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2026-07-16 UTC."],[],[]]

Web Proxy Viewer  |  New URL  |  Original Page