Bestätigung für Android Protected

Um die Absicht von Nutzern zu bestätigen, wenn sie eine vertrauliche Transaktion wie eine Zahlung initiieren, können Sie auf unterstützten Geräten mit Android 9 (API-Level 28) oder höher die Android Protected Confirmation verwenden. Bei diesem Ablauf wird in Ihrer App eine Aufforderung angezeigt, in der der Nutzer eine kurze Erklärung bestätigen muss, die seine Absicht zum Abschluss der vertraulichen Transaktion bekräftigt.

Wenn der Nutzer die Erklärung akzeptiert, kann Ihre App einen Schlüssel aus dem Android-Schlüsselspeicher verwenden, um die im Dialogfeld angezeigte Nachricht zu signieren. Die Signatur weist mit sehr hoher Wahrscheinlichkeit darauf hin, dass der Nutzer die Erklärung gesehen und ihr zugestimmt hat.

Achtung : Android Protected Confirmation bietet keinen sicheren Informationskanal für den Nutzer. Ihre App kann keine Vertraulichkeitsgarantien annehmen, die über die von der Android-Plattform angebotenen hinausgehen. Verwenden Sie diesen Workflow insbesondere nicht, um vertrauliche Informationen anzuzeigen, die Sie normalerweise nicht auf dem Gerät des Nutzers anzeigen würden.

Nachdem der Nutzer die Nachricht bestätigt hat, ist ihre Integrität gewährleistet. Ihre App muss jedoch weiterhin die Verschlüsselung von Daten während der Übertragung verwenden, um die Vertraulichkeit der signierten Nachricht zu schützen.

So bieten Sie Unterstützung für die Nutzerbestätigung mit hoher Sicherheit in Ihrer App:

  1. Asymmetrischen Signaturschlüssel generieren mit der Klasse KeyGenParameterSpec.Builder. Übergeben Sie beim Erstellen des Schlüssels true an setUserConfirmationRequired(). Rufen Sie außerdem setAttestationChallenge() auf und übergeben Sie einen geeigneten Challenge-Wert, der von der vertrauenden Partei bereitgestellt wird.

  2. Registrieren Sie den neu generierten Schlüssel und das Attestierungszertifikat des Schlüssels bei der entsprechenden vertrauenden Partei.

  3. Senden Sie Transaktionsdetails an Ihren Server und lassen Sie ihn ein BLOB (Binary Large Object) mit zusätzlichen Daten generieren und zurückgeben. Zusätzliche Daten können die zu bestätigenden Daten oder Parsing-Hinweise wie die Sprache des Prompt-Strings enthalten.

    Für eine sicherere Implementierung muss der BLOB eine kryptografische Nonce enthalten, um vor Replay-Angriffen zu schützen und Transaktionen zu disambiguieren.

  4. Richten Sie das ConfirmationCallback-Objekt ein, das Ihre App darüber informiert, wenn der Nutzer die Aufforderung in einem Bestätigungsdialogfeld akzeptiert hat:

    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()
              // Handle case where your app closed the dialog before the user
              // responded to the prompt.
          }
    
          override fun onError(e: Exception?) {
              super.onError(e)
              // Handle the exception that the callback captured.
          }
      }

    Java

    public class MyConfirmationCallback extends ConfirmationCallback {
    
      @Override
      public void onConfirmed(@NonNull byte[] dataThatWasConfirmed) {
          super.onConfirmed(dataThatWasConfirmed);
          // Sign dataThatWasConfirmed using your generated signing key.
          // By completing this process, you generate a signed statement.
      }
    
      @Override
      public void onDismissed() {
          super.onDismissed();
          // Handle case where user declined the prompt in the
          // confirmation dialog.
      }
    
      @Override
      public void onCanceled() {
          super.onCanceled();
          // Handle case where your app closed the dialog before the user
          // responded to the prompt.
      }
    
      @Override
      public void onError(Throwable e) {
          super.onError(e);
          // Handle the exception that the callback captured.
      }
    }

    Wenn der Nutzer das Dialogfeld bestätigt, wird der Callback onConfirmed() aufgerufen. Der dataThatWasConfirmed-BLOB ist eine CBOR-Datenstruktur, die unter anderem den Aufforderungstext enthält, den der Nutzer gesehen hat, sowie die zusätzlichen Daten, die Sie in den Builder ConfirmationPrompt übergeben haben. Signieren Sie den dataThatWasConfirmed-BLOB mit dem zuvor erstellten Schlüssel und geben Sie diesen BLOB zusammen mit der Signatur und den Transaktionsdetails an die vertrauende Partei zurück.

    Damit die Sicherheit, die durch die geschützte Bestätigung von Android geboten wird, voll ausgeschöpft werden kann, muss die vertrauende Partei nach Erhalt einer signierten Nachricht die folgenden Schritte ausführen:

    1. Prüfen Sie die Signatur der Nachricht sowie die Attestierungszertifikatskette des Signierschlüssels.
    2. Prüfen Sie, ob das Attestierungszertifikat das Flag TRUSTED_CONFIRMATION_REQUIRED hat. Dieses Flag gibt an, dass für den Signaturschlüssel eine Bestätigung durch einen vertrauenswürdigen Nutzer erforderlich ist. Wenn der Signaturschlüssel ein RSA-Schlüssel ist, prüfen Sie, ob er die Eigenschaft PURPOSE_ENCRYPT oder PURPOSE_DECRYPT hat.
    3. Prüfen Sie in extraData, ob diese Bestätigungsmeldung zu einer neuen Anfrage gehört und noch nicht verarbeitet wurde. Dieser Schritt schützt vor Wiederholungsversuchen.
    4. Parst die promptText, um Informationen zur bestätigten Aktion oder Anfrage zu erhalten. Denken Sie daran, dass promptText der einzige Teil der Nachricht ist, den der Nutzer tatsächlich bestätigt hat. Die vertrauende Partei darf niemals davon ausgehen, dass die zu bestätigenden Daten in extraData mit der promptText übereinstimmen.
  5. Fügen Sie Logik hinzu, die der im folgenden Code-Snippet gezeigten ähnelt, um den Dialog selbst anzuzeigen:

    Kotlin

    // This data structure varies by app type. This is 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 -> runnable.run() }
      val callback = MyConfirmationCallback()
    
      val dialog = ConfirmationPrompt.Builder(context)
              .setPromptText("${myDialogData.sender}, send
                              ${myDialogData.amount} to
                              ${myDialogData.receiver}?")
              .setExtraData(myExtraData)
              .build()
      dialog.presentPrompt(threadReceivingCallback, callback)

    Java

      // This data structure varies by app type. This is an example.
      class ConfirmationPromptData {
          String sender, receiver, amount;
          ConfirmationPromptData(String sender, String receiver, String amount) {
              this.sender = sender;
              this.receiver = receiver;
              this.amount = amount;
          }
      };
      final int MY_EXTRA_DATA_LENGTH = 100;
      byte[] myExtraData = new byte[MY_EXTRA_DATA_LENGTH];
      ConfirmationPromptData myDialogData = new ConfirmationPromptData("Ashlyn", "Jordan", "$500");
      Executor threadReceivingCallback = Runnable::run;
      MyConfirmationCallback callback = new MyConfirmationCallback();
      ConfirmationPrompt dialog = (new ConfirmationPrompt.Builder(getApplicationContext()))
              .setPromptText("${myDialogData.sender}, send ${myDialogData.amount} to ${myDialogData.receiver}?")
              .setExtraData(myExtraData)
              .build();
      dialog.presentPrompt(threadReceivingCallback, callback);

Zusätzliche Ressourcen

Weitere Informationen zur geschützten Bestätigung unter Android finden Sie in den folgenden Ressourcen.

Blogs