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:
Erstellen Sie einen asymmetrischen Signaturschlüssel mit der Klasse
KeyGenParameterSpec.Builder
. Geben Sie beim Erstellen des Schlüsselstrue
ansetUserConfirmationRequired()
weiter. Rufen Sie außerdemsetAttestationChallenge()
an, Übergabe eines von der vertrauenden Partei angegebenen Werts für die IdentitätsbestätigungRegistrieren Sie den neu generierten Schlüssel und das Attestierungszertifikat Ihres Schlüssels mit die entsprechende vertrauende Partei an.
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.
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 BLOBdataThatWasConfirmed
ist ein CBOR-Datenstruktur, die Folgendes enthält: den Prompt-Text, den der Nutzer gesehen hat, sowie der zusätzliche Daten, die Sie an dieConfirmationPrompt
des Website-Builders enthält. Verwenden Sie den zuvor erstellten Schlüssel, um dendataThatWasConfirmed
-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:
- Signatur und Attestierung der Nachricht prüfen Zertifikatskette des Signaturschlüssels.
- 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 AttributPURPOSE_ENCRYPT
oderPURPOSE_DECRYPT
hat. - 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. - Parse die
promptText
nach Informationen zur bestätigten Aktion oder Anfrage. Denken Sie daran, dasspromptText
der einzige Teil der Nachricht ist, den der Nutzer tatsächlich bestätigt hat. Die vertrauende Partei darf niemals davon ausgehen, dass die inextraData
enthaltenen zu bestätigenden Daten denpromptText
entsprechen.
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.