Bestätigung für Android Protected

Um die Absichten von Nutzern zu bestätigen, wenn sie eine sensible Transaktion wie eine Zahlung initiieren, können Sie auf unterstützten Geräten mit Android 9 (API-Level 28) oder höher die Funktion „Android geschützte Nutzereingabe“ verwenden. Bei Verwendung dieses wird der Nutzer in der App aufgefordert, ein Short zu genehmigen. , mit der die Absicht bekräftigt wird, die vertrauliche Transaktion abzuschließen.

Wenn der Nutzer die Anweisung akzeptiert, kann deine App einen Schlüssel aus dem Android Keystore verwenden um die im Dialogfeld angezeigte Nachricht zu signieren. Die Unterschrift gibt mit sehr hoher Wahrscheinlichkeit an, dass der Nutzer die Erklärung gelesen und ihr zugestimmt hat.

Achtung : Die Android Protected-Bestätigung enthält keine Informationskanal für den Nutzer. Ihre App kann keine Vertraulichkeitsgarantien übernehmen, die über die der Android-Plattform 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 während der Übertragung verwenden, um die Vertraulichkeit der signierten Nachricht zu schützen.

So unterstützen Sie die Bestätigung mit hoher Sicherheit in Ihrer App:

  1. Erstellen Sie einen asymmetrischen Signaturschlüssel mit der Klasse KeyGenParameterSpec.Builder. Geben Sie beim Erstellen des Schlüssels true an setUserConfirmationRequired() weiter. Rufen Sie außerdem setAttestationChallenge() an, Übergabe eines von der vertrauenden Partei angegebenen Werts für die Identitätsbestätigung

  2. Registrieren Sie den neu generierten Schlüssel und das Attestierungszertifikat Ihres Schlüssels mit die entsprechende vertrauende Partei an.

  3. Transaktionsdetails an Ihren Server senden und diesen generieren und eine BLOB (Binary Large Object) mit zusätzlichen Daten Zu den zusätzlichen Daten können die zu bestätigenden Daten oder Parsing-Hinweise wie die Sprache des Prompt-Strings gehören.

    Für eine sicherere Implementierung muss der BLOB ein kryptografisches Nonce zum Schutz vor Replay-Angriffen und zur Unterscheidung von Transaktionen enthalten.

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

    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.
          }
      }
    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 genehmigt, ist der onConfirmed()-Callback aufgerufen. Der BLOB dataThatWasConfirmed ist ein CBOR-Datenstruktur, die Folgendes enthält: den Prompt-Text, den der Nutzer gesehen hat, sowie der zusätzliche Daten, die Sie an die ConfirmationPrompt des Website-Builders enthält. Verwenden Sie den zuvor erstellten Schlüssel, um den dataThatWasConfirmed-BLOB zu signieren, und geben Sie diesen BLOB zusammen mit der Signatur und den Transaktionsdetails an die vertrauende Partei zurück.

    Um die Sicherheitsvorkehrungen von Android Protected Confirmation vollumfänglich zu nutzen, muss die vertrauende Partei nach Erhalt einer signierten Nachricht die folgenden Schritte ausführen:

    1. Signatur und Attestierung der Nachricht prüfen Zertifikatskette des Signaturschlüssels.
    2. Prüfen Sie, ob das Attestierungszertifikat die Das Flag TRUSTED_CONFIRMATION_REQUIRED wurde festgelegt, das angibt, dass die Signatur Schlüssel erfordert die Bestätigung eines vertrauenswürdigen Nutzers. Wenn der Signaturschlüssel ein RSA-Schlüssel ist, prüfen Sie, ob er nicht das Attribut PURPOSE_ENCRYPT oder PURPOSE_DECRYPT hat.
    3. Prüfen Sie, ob diese Bestätigungsnachricht zu extraData gehört eine neue Anfrage gesendet wurde und noch nicht verarbeitet wurde. Dieser Schritt schützt vor Replay-Angriffen.
    4. Parse die promptText nach Informationen zur bestätigten Aktion oder Anfrage. 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 in extraData enthaltenen zu bestätigenden Daten den promptText entsprechen.
  5. Fügen Sie eine Logik wie im folgenden Code-Snippet hinzu, um das Ereignis Dialogfeld selbst:

    // 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)
      // 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);

Weitere Informationen

Weitere Informationen zur Android Protected Confirmation finden Sie hier: Ressourcen.

Blogs