Passkey erstellen

Bevor sich Ihre Nutzer mit Passkeys authentifizieren können, muss Ihre App den Passkey zuerst für ihr Konto registrieren oder erstellen.

Um den Passkey zu erstellen, rufen Sie die Details ab, die zum Erstellen des Passkeys erforderlich sind, und rufen Sie dann die Credential Manager API auf, die ein öffentliches und ein privates Schlüsselpaar zurückgibt. Der zurückgegebene private Schlüssel wird in einem Anmeldedatenanbieter wie dem Google Passwortmanager als Passkey gespeichert. Der öffentliche Schlüssel wird auf Ihrem App-Server gespeichert.

Passkeys werden in einem Anmeldedatenanbieter und öffentliche Schlüssel auf dem App-Server gespeichert.
Abbildung 1: Erstellung von Passkeys

Vorbereitung

Achten Sie darauf, dass Sie Digital Asset Links eingerichtet haben und dass Sie Geräte mit Android 9 (API-Level 28) oder höher verwenden.

Übersicht

In dieser Anleitung werden die Änderungen beschrieben, die in Ihrer Client-App der vertrauenden Partei erforderlich sind, um einen Passkey zu erstellen. Außerdem wird eine kurze Übersicht über die Implementierung des App-Servers der vertrauenden Partei gegeben. Weitere Informationen zur serverseitigen Integration finden Sie unter Serverseitige Passkey-Registrierung.

  1. Abhängigkeiten zu Ihrer App hinzufügen: Fügen Sie die erforderlichen Credential Manager Bibliotheken hinzu.
  2. **Credential Manager instanziieren**: Erstellen Sie eine Credential Manager -Instanz.
  3. Optionen zur Erstellung von Anmeldedaten vom App-Server abrufen: Senden Sie von Ihrem App-Server die Details, die zum Erstellen des Passkeys erforderlich sind, an die Client-App, z. B. Informationen zur App, zum Nutzer sowie eine challenge und andere Felder.
  4. Passkey anfordern: Verwenden Sie in Ihrer App die vom App- Server empfangenen Details, um ein GetPublicKeyCredentialOption-Objekt zu erstellen, und verwenden Sie dieses Objekt, um die Methode credentialManager.getCredential() aufzurufen, um einen Passkey zu erstellen.
  5. Antwort auf die Passkey-Erstellung verarbeiten: Wenn Sie die Anmeldedaten in Ihrer Client-App erhalten, müssen Sie den öffentlichen Schlüssel codieren, serialisieren und dann an den App-Server senden. Sie müssen auch alle Ausnahmen verarbeiten, die bei der Passkey-Erstellung auftreten können.
  6. Öffentlichen Schlüssel auf dem Server überprüfen und speichern: Führen Sie die serverseitigen Schritte aus, um den Ursprung der Anmeldedaten zu überprüfen, und speichern Sie dann den öffentlichen Schlüssel.
  7. Nutzer benachrichtigen: Benachrichtigen Sie den Nutzer, dass sein Passkey erstellt wurde.

Abhängigkeiten zu Ihrer App hinzufügen

Fügen Sie der Datei build.gradle Ihres App-Moduls die folgenden Abhängigkeiten hinzu:

Kotlin

dependencies {
    implementation("androidx.credentials:credentials:1.7.0-alpha02")
    implementation("androidx.credentials:credentials-play-services-auth:1.7.0-alpha02")
}

Groovy

dependencies {
    implementation "androidx.credentials:credentials:1.7.0-alpha02"
    implementation "androidx.credentials:credentials-play-services-auth:1.7.0-alpha02"
}
eine UnsupportedOperationException("Post-U not supported yet") Ausnahme aus.

Credential Manager instanziieren

Erstellen Sie mit dem App- oder Aktivitätskontext ein CredentialManager-Objekt.

// Use your app or activity context to instantiate a client instance of
// CredentialManager.
private val credentialManager = CredentialManager.create(context)

Optionen zur Erstellung von Anmeldedaten von Ihrem App-Server abrufen

Wenn der Nutzer auf die Schaltfläche „Passkey erstellen“ klickt oder sich ein neuer Nutzer registriert, senden Sie eine Anfrage von Ihrer App an Ihren App-Server, um die Informationen abzurufen, die zum Starten des Passkey-Registrierungsprozesses erforderlich sind.

Verwenden Sie eine FIDO-konforme Bibliothek auf Ihrem App-Server, um Ihrer Client-App die Informationen zu senden, die zum Erstellen eines Passkeys erforderlich sind, z. B. Informationen zum Nutzer, zur App und zusätzliche Konfigurationseigenschaften. Weitere Informationen finden Sie unter Serverseitige Passkey-Registrierung.

Decodieren Sie in der Client-App die vom App-Server gesendeten Optionen zur Erstellung des öffentlichen Schlüssels. Diese werden normalerweise im JSON-Format dargestellt. Weitere Informationen zum Decodieren für Webclients finden Sie unter Codierung und Decodierung. Für Android-Client-Apps müssen Sie die Decodierung separat verarbeiten.

Das folgende Snippet zeigt die Struktur der Optionen zur Erstellung des öffentlichen Schlüssels, die vom App-Server gesendet werden:

{
  "challenge": "<base64url-encoded challenge>",
  "rp": {
    "name": "<relying party name>",
    "id": "<relying party host name>"
  },
  "user": {
    "id": "<base64url-encoded user ID>",
    "name": "<user name>",
    "displayName": "<user display name>"
  },
  "pubKeyCredParams": [
    {
      "type": "public-key",
      "alg": -7
    }
  ],
  "attestation": "none",
  "excludeCredentials": [
    {
        "id": "<base64url-encoded credential ID to exclude>", 
        "type": "public-key"
    }
  ],
  "authenticatorSelection": {
    "requireResidentKey": true,
    "residentKey": "required",
    "userVerification": "required"
  }
}

Zu den wichtigsten Feldern in den Optionen zur Erstellung des öffentlichen Schlüssels gehören:

  • challenge: Ein vom Server generierter Zufallsstring, der verwendet wird, um Replay-Angriffe zu verhindern.
  • rp: Details zur App.
    • rp.name: Der Name der App.
    • rp.id: Die Domain oder Subdomain der App.
  • user: Details zum Nutzer.
    • id: Die eindeutige ID des Nutzers. Dieser Wert darf keine personenidentifizierbaren Informationen wie E-Mail-Adressen oder Nutzernamen enthalten. Sie können einen zufälligen 16-Byte-Wert verwenden.
    • name: Eine eindeutige Kennung für das Konto, die der Nutzer erkennt, z. B. seine E-Mail-Adresse oder sein Nutzername. Diese wird in der Kontoauswahl angezeigt. Wenn Sie einen Nutzernamen verwenden, verwenden Sie denselben Wert wie bei der Passwortauthentifizierung.
    • displayName: Ein optionaler, nutzerfreundlicher Name für das Konto, der in der Kontoauswahl angezeigt werden soll.
  • authenticatorSelection: Details zum Gerät, das für die Authentifizierung verwendet wird.

    • authenticatorAttachment: Gibt den bevorzugten Authentifikator an. Folgende Werte sind möglich: - platform: Dieser Wert wird für einen Authentifikator verwendet, der in das Gerät des Nutzers integriert ist, z. B. ein Fingerabdrucksensor. - cross-platform: Dieser Wert wird für Roaming-Geräte wie Sicherheitsschlüssel verwendet. Er wird normalerweise nicht im Passkey-Kontext verwendet. - Nicht angegeben (empfohlen): Wenn Sie diesen Wert nicht angeben, können Nutzer Passkeys auf ihren bevorzugten Geräten erstellen. In den meisten Fällen ist es die beste Option, den Parameter nicht anzugeben.
      • requireResidentKey: Setzen Sie den Wert dieses Boolean-Felds auf true, um einen Passkey zu erstellen.
      • residentKey: Setzen Sie den Wert auf required, um einen Passkey zu erstellen.
      • userVerification: Wird verwendet, um die Anforderungen für die Nutzerüberprüfung während der Passkey-Registrierung anzugeben. Folgende Werte sind möglich: - preferred: Verwenden Sie diesen Wert, wenn Sie die Nutzererfahrung gegenüber dem Schutz priorisieren, z. B. in Umgebungen, in denen die Nutzerüberprüfung mehr Reibung als Schutz verursacht. - required: Verwenden Sie diesen Wert, wenn eine auf dem Gerät verfügbare Methode zur Nutzerüberprüfung aufgerufen werden muss. - discouraged: Verwenden Sie diesen Wert, wenn die Verwendung einer Methode zur Nutzerüberprüfung nicht empfohlen wird.
        Weitere Informationen zu userVerification, siehe userVerification im Detail.
  • excludeCredentials: Listen Sie Anmeldedaten-IDs in einem Array auf, um zu verhindern, dass ein doppelter Passkey erstellt wird, wenn bereits einer mit demselben Anmeldedatenanbieter vorhanden ist.

Passkey erstellen

Nachdem Sie die serverseitigen Optionen zur Erstellung des öffentlichen Schlüssels geparst haben, erstellen Sie einen Passkey, indem Sie diese Optionen in ein CreatePublicKeyCredentialRequest-Objekt einfügen und createCredential() aufrufen.

Die createPublicKeyCredentialRequest enthält Folgendes:

  • requestJson: Die vom App-Server gesendeten Optionen zur Erstellung von Anmeldedaten.
  • preferImmediatelyAvailableCredentials: Dies ist ein optionales boolesches Feld , das festlegt, ob nur lokal verfügbare oder mit dem Anmeldedaten Bereitsteller synchronisierte Anmeldedaten verwendet werden sollen, um die Anfrage zu erfüllen, anstatt Anmeldedaten von Sicherheitsschlüsseln oder Hybrid-Schlüsselabläufen. Folgende Verwendungen sind möglich:
    • false (Standard): Verwenden Sie diesen Wert, wenn der Aufruf von Credential Manager durch eine explizite Nutzeraktion ausgelöst wurde.
    • true: Verwenden Sie diesen Wert, wenn Credential Manager opportunistisch aufgerufen wird, z. B. beim ersten Öffnen der App.
      Wenn Sie den Wert auf true setzen und keine sofort verfügbaren Anmeldedaten vorhanden sind, zeigt Credential Manager keine UI an und die Anfrage schlägt sofort fehl. Für Abrufanfragen wird „NoCredentialException“ und für Erstellungsanfragen CreateCredentialNoCreateOptionException zurückgegeben.
  • origin: Dieses Feld wird für Android-Apps automatisch festgelegt. Informationen zum Festlegen von origin für Browser und ähnlich privilegierte Apps finden Sie unter Credential Manager-Aufrufe im Namen anderer Parteien für privilegierte Apps.
  • isConditional: Dies ist ein optionales Feld, dessen Standardwert false ist. Weitere Informationen finden Sie unter Passkey automatisch erstellen.

Durch Aufrufen der Funktion createCredential() wird die integrierte Ansicht am unteren Rand von Credential Manager gestartet, in der der Nutzer aufgefordert wird, einen Passkey zu verwenden und einen Anmeldedatenanbieter und ein Konto für die Speicherung auszuwählen. Wenn isConditional jedoch auf true gesetzt ist, wird die Bottom-Sheet-UI nicht angezeigt und der Passkey wird automatisch erstellt.

Passkey automatisch erstellen

Sie können nach einer erfolgreichen Passwortanmeldung automatisch einen Passkey für einen Nutzer erstellen, indem Sie beim Erstellen eines Passkeys den Parameter isConditional in Ihrer CreatePublicKeyCredentialRequest auf true setzen. Wenn der Nutzer noch keinen Passkey hat, versucht Ihre App automatisch, einen im Hintergrund zu erstellen und ihn im Anmeldedatenanbieter des Nutzers zu speichern, z. B. im Google Passwortmanager. Ein Beispiel für die Implementierung finden Sie im öffentlichen Beispiel.

Beispiel für die Benachrichtigung, die der Google Passwortmanager nach der Passkey-Erstellung anzeigt
Abbildung 2: Google Passwortmanager-Benachrichtigung

Antwort verarbeiten

Nachdem der Nutzer mit der Displaysperre des Geräts überprüft wurde, wird ein Passkey erstellt und im ausgewählten Anmeldedatenanbieter des Nutzers gespeichert.

Die Antwort nach einem erfolgreichen Aufruf von createCredential() ist ein PublicKeyCredential-Objekt.

Die PublicKeyCredential sieht so aus:

{
  "id": "<identifier>",
  "type": "public-key",
  "rawId": "<identifier>",
  "response": {
    "clientDataJSON": "<ArrayBuffer encoded object with the origin and signed challenge>",
    "attestationObject": "<ArrayBuffer encoded object with the public key and other information.>"
  },
  "authenticatorAttachment": "platform"
}

Serialisieren Sie das Objekt in der Client-App und senden Sie es an den App-Server.

Fügen Sie Code hinzu, um Fehler zu verarbeiten, wie im folgenden Snippet gezeigt:

fun handleFailure(e: CreateCredentialException) {
    when (e) {
        is CreatePublicKeyCredentialDomException -> {
            // Handle the passkey DOM errors thrown according to the
            // WebAuthn spec.
        }
        is CreateCredentialCancellationException -> {
            // The user intentionally canceled the operation and chose not
            // to register the credential.
        }
        is CreateCredentialInterruptedException -> {
            // Retry-able error. Consider retrying the call.
        }
        is CreateCredentialProviderConfigurationException -> {
            // Your app is missing the provider configuration dependency.
            // Most likely, you're missing the
            // "credentials-play-services-auth" module.
        }
        is CreateCredentialCustomException -> {
            // You have encountered an error from a 3rd-party SDK. If you
            // make the API call with a request object that's a subclass of
            // CreateCustomCredentialRequest using a 3rd-party SDK, then you
            // should check for any custom exception type constants within
            // that SDK to match with e.type. Otherwise, drop or log the
            // exception.
        }
        else -> Log.w(TAG, "Unexpected exception type ${e::class.java.name}")
    }
}

Öffentlichen Schlüssel auf dem App-Server überprüfen und speichern

Auf dem App-Server müssen Sie die Anmeldedaten des öffentlichen Schlüssels überprüfen und dann den öffentlichen Schlüssel speichern.

Um den Ursprung der Anmeldedaten des öffentlichen Schlüssels zu überprüfen, vergleichen Sie sie mit einer Zulassungsliste genehmigter Apps. Wenn ein Schlüssel einen unbekannten Ursprung hat, lehnen Sie ihn ab.

So rufen Sie den SHA‑256-Fingerabdruck der App ab:

  1. Geben Sie das Signaturzertifikat Ihrer Release-App aus, indem Sie den folgenden Befehl in einem Terminal ausführen:

    keytool -list -keystore <path-to-apk-signing-keystore>
    

    Suchen Sie in der Antwort nach dem SHA‑256-Fingerabdruck des Signaturzertifikats, der als Certificate fingerprints block : SHA256 angegeben ist.

  2. Codieren Sie den SHA‑256-Fingerabdruck mit der Base64url-Codierung. Dieses Python-Beispiel zeigt, wie Sie den Fingerabdruck richtig codieren:

    import binascii
    import base64
    fingerprint = '<SHA256 finerprint>' # your app's SHA256 fingerprint
    print(base64.urlsafe_b64encode(binascii.a2b_hex(fingerprint.replace(':', ''))).decode('utf8').replace('=', ''))
    
  3. Hängen Sie android:apk-key-hash: an den Anfang der Ausgabe aus dem vorherigen Schritt an, sodass das Ergebnis in etwa so aussieht:

    android:apk-key-hash:<encoded SHA 256 fingerprint>
    

    Das Ergebnis muss mit einem zulässigen Ursprung auf Ihrem App-Server übereinstimmen. Wenn Sie mehrere Signaturzertifikate haben, z. B. Zertifikate für das Debugging und die Release-Version, oder mehrere Apps, wiederholen Sie den Vorgang und akzeptieren Sie alle Ursprünge als gültig auf dem App-Server.

Nutzer benachrichtigen

Nachdem der Passkey erfolgreich erstellt wurde, benachrichtigen Sie Ihre Nutzer darüber und informieren Sie sie, dass sie ihre Passkeys in der App ihres Anmeldedatenanbieters oder in den App-Einstellungen verwalten können. Benachrichtigen Sie Nutzer über ein benutzerdefiniertes Dialogfeld, eine Benachrichtigung oder eine Snackbar. Da eine unerwartete Passkey-Erstellung durch eine böswillige Entität eine sofortige Sicherheitswarnung erfordert, sollten Sie diese In-App-Methoden durch externe Kommunikation ergänzen, z. B. per E-Mail.

Nutzerfreundlichkeit verbessern

Um die Nutzerfreundlichkeit bei der Implementierung der Registrierung mit Credential Manager zu verbessern, sollten Sie Funktionen zum Wiederherstellen von Anmeldedaten und zum Unterdrücken von Autofill-Dialogfeldern hinzufügen.

Funktion zum Wiederherstellen von Anmeldedaten auf einem neuen Gerät hinzufügen

Implementieren Sie die Funktion zum Wiederherstellen von Anmeldedaten, damit sich Nutzer nahtlos auf einem neuen Gerät in ihre Konten einloggen können. Wenn Sie die Funktion zum Wiederherstellen von Anmeldedaten mit BackupAgent hinzufügen, werden Nutzer angemeldet, wenn sie Ihre wiederhergestellte App auf einem neuen Gerät öffnen. So können sie Ihre App sofort verwenden.

Autofill in Anmeldedatenfeldern unterdrücken (optional)

Fügen Sie für App-Bildschirme, auf denen Nutzer die Bottom-Sheet-UI von Credential Manager zur Authentifizierung verwenden sollen, das Attribut isCredential zu den Feldern für Nutzernamen und Passwort hinzu. Dadurch wird verhindert, dass sich Autofill-Dialogfelder (FillDialog und SaveDialog) mit der Ansicht am unteren Rand von Credential Manager überschneiden.

Das Attribut isCredential wird unter Android 14 und höher unterstützt.

Das folgende Beispiel zeigt, wie Sie das Attribut isCredential den entsprechenden Feldern für Nutzernamen und Passwort in den relevanten Ansichten für Ihre App hinzufügen können:

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:isCredential="true" />

Nächste Schritte