Android Protected Confirmation

To help you confirm users' intentions when they initiate a sensitive transaction, such as making a payment, supported devices that run Android 9 (API level 28) or higher let you use Android Protected Confirmation. When using this workflow, your app displays a prompt to the user, asking them to approve a short statement that reaffirms their intent to complete the sensitive transaction.

If the user accepts the statement, your app can use a key from Android Keystore to sign the message shown in the dialog. The signature indicates, with very high confidence, that the user has seen the statement and has agreed to it.

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

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

To provide support for 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 binary large object (BLOB) of extra data. Extra data might include the to-be-confirmed data or parsing hints, such as the locale of the prompt string.

    For a more secure implementation, the BLOB must contain a cryptographic nonce for protection against replay attacks and to disambiguate transactions.

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

    Kotlin

    class MyConfirmationCallback : ConfirmationCallback() {
    
          override fun onConfirmed(dataThatWasConfirmed: ByteArray?) {
              super.onConfirmed(dataThatWasConfirmed)
              // Sign dataThatWasConfirmed using your generated signing key.
              // By completing this process, you generate a signed statement.
          }
    
          override fun onDismissed() {
              super.onDismissed()
              // Handle case where user declined the prompt in the
              // confirmation dialog.
          }
    
          override fun onCanceled() {
              super.onCanceled()