Skip to content

Most visited

Recently visited


Security updates

Android P introduces a number of new features that enhance the security of your app and the devices that run them. This page describes the changes that are most important for third-party app developers to keep in mind.

Unified fingerprint authentication dialog

In Android P, the system provides fingerprint authentication dialogs on behalf of your app. This functionality creates a standardized look, feel, and placement for the dialog, giving users more confidence that they're authenticating against a trusted fingerprint credential checker.

If your app uses' FingerprintManager to display a fingerprint authentication dialog to users, migrate your app's logic to use FingerprintDialog instead, which relies on the system to display the dialog.

High-assurance user confirmation

Supported devices that launch with Android P installed give you the ability to use the Protected Confirmation API. By using this new API, your app can use an instance of ConfirmationDialog to display a prompt to the user, asking them to approve a short statement. This statement allows the app to reaffirm that the user would like to complete a sensitive transaction, such as making a payment.

If the user accepts the statement, your app receives a cryptographic signature that's protected by a keyed-hash message authentication code (HMAC). The signature is produced by the trusted execution environment (TEE), which protects the display of the confirmation dialog as well as user input. The signature indicates, with very high confidence, that the user has seen the statement and has agreed to it.

Caution: The Protected Confirmation API doesn't provide a secure information channel for the user. Your app cannot assume any confidentiality guarantees beyond those that the Android platform offers. In particular, don't use this API to display sensitive information that you wouldn't ordinarily show on the user's device.

After the user confirms the message, its integrity is assured, but your app must still use data-in-transit encryption to assure the confidentiality of the signed message.

To provide high-assurance user confirmation in your app, complete the following steps:

  1. Generate an asymmetric signing key using the KeyGenParameterSpec.Builder class. When creating the key, pass true into setUserConfirmationRequired(). Also, call setAttestationChallenge(), passing a suitable challenge value provided by the relying party.

  2. Enroll the newly-generated key and your key's attestation certificate with the appropriate relying party.

  3. Send transaction details to your server and have it generate and return a blob of extra data. For example, the extra data of a financial transaction might comprise the amount, origin account, and destination account. The blob should contain a cryptographic nonce for protection against replay attacks, and the blob might also contain app-specific data. Your server should store the blob and transaction details locally.

  4. Set up the ConfirmationCallback object that informs your app when the user has accepted the prompt shown in a confirmation dialog:

    class MyConfirmationCallback : ConfirmationCallback() {
        override fun onConfirmedByUser(dataThatWasConfirmed: ByteArray?) {
            // Sign dataThatWasConfirmed using your generated signing key.
            // By completing this process, you generate a "signed statement".
        override fun onDismissedByUser() {
            // Handle case where user declined the prompt in the
            // confirmation dialog.
        override fun onDismissedByApplication() {
            // Handle case where your app closed the dialog before the user
            // could respond to the prompt.
        override fun onError(e: Exception?) {
            // Handle the exception that the callback captured.

    If the user approves the dialog, the onConfirmedByUser() callback is called. The dataThatWasConfirmed blob is a CBOR data structure that contains, among other details, the prompt text that the user saw as well as the extra data that you passed into the ConfirmationDialog builder. Your app should use the previously-created key to sign the dataThatWasConfirmed blob. You should then pass this blob, along with the signature and transaction details, back to the relying party.

    After receiving the signature, your server should check it. If the signature is valid, you can then extract extraData and promptText from dataThatWasConfirmed and verify that extraData matches what was previously stored. As a final check, your server should check that the promptText corresponds to the transaction details that appear in the extra data. If this step succeeds, your server can carry out the transaction, knowing with a high degree of confidence that the user has seen and approved the message in promptText.

  5. Add logic similar to that shown in the following code snippet to display the dialog itself:

    // This data structure varies by app type. This is just an example.
    data class ConfirmationPromptData(val sender: String,
            val receiver: String, val amount: String)
    val myExtraData: ByteArray = byteArrayOf()
    val myDialogData = ConfirmationPromptData("Ashlyn", "Jordan", "$500")
    val threadReceivingCallback = Executor { runnable -> }
    val callback = MyConfirmationCallback()
    val dialog = ConfirmationDialog.Builder()
            .setPromptText("${myDialogData.sender}, send
                            ${myDialogData.amount} to
    dialog.presentPrompt(threadReceivingCallback, callback)

Hardware security module

Supported devices that are launched with Android P installed can have a StrongBox Keymaster, an implementation of the Keymaster HAL that resides in a hardware security module. The module contains its own CPU, secure storage, a true random-number generator, and additional mechanisms to resist package tampering and unauthorized sideloading of apps. When checking keys stored in the StrongBox Keymaster, the system corroborates a key's integrity with the Trusted Execution Environment (TEE).

To support low-power StrongBox implementations, a subset of algorithms and key sizes are supported:

When generating or importing keys using the KeyStore class, you indicate a preference for storing the key in the StrongBox Keymaster by passing true to the setIsStrongBoxBacked() method in either the KeyGenParameterSpec.Builder class or the KeyProtection.Builder class.

Secure key import into Keystore

Android P provides additional key decryption security by adding the ability to import encrypted keys securely into the Keystore using a new ASN.1‑encoded key format. The Keymaster then decrypts the keys in the Keystore, so the content of the keys never appears as plaintext in the device's host memory.

To support secure importing of encrypted keys into the Keystore, complete the following steps:

  1. Generate a key pair that uses the PURPOSE_WRAP_KEY purpose. It's recommended that you add attestation to this key pair, as well.

  2. On a server or machine that you trust, generate the ASN.1 message that the SecureKeyWrapper should contain.

    The wrapper contains the following schema:

    KeyDescription ::= SEQUENCE {
        keyFormat INTEGER,
        authorizationList AuthorizationList
    SecureKeyWrapper ::= SEQUENCE {
        wrapperFormatVersion INTEGER,
        encryptedTransportKey OCTET_STRING,
        initializationVector OCTET_STRING,
        keyDescription KeyDescription,
        secureKey OCTET_STRING,
        tag OCTET_STRING
  3. Create a WrappedKeyEntry object, passing in the ASN.1 message as a byte array.

  4. Pass this WrappedKeyEntry object into the overload of setEntry() that accepts a Keystore.Entry object.

This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields


Follow Google Developers on WeChat

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience. (Dec 2017 Android Platform & Tools Survey)