Online-Akzeptanz digitaler Anmeldedaten

Digitale IDs können sowohl in der App als auch im Web akzeptiert werden. So akzeptieren Sie Anmeldedaten von Google Wallet:

  1. Binden Sie die Funktion mithilfe der App oder des Webs ein und folgen Sie der Anleitung.
  2. Verwenden Sie die Test-ID, um Ihren Ablauf in der Sandbox von Google Wallet zu testen.
  3. Wenn Sie bereit sind, die Funktion zu aktivieren, füllen Sie dieses Formular aus, um die Nutzungsbedingungen für die Annahme von Anmeldedaten aus Google Wallet anzufordern und ihnen zuzustimmen. Sie müssen dieses Formular für jede Ihrer Rechtssubjekte ausfüllen.
  4. Bei Fragen können Sie sich an wallet-identity-rp-support@google.com wenden.

Vorbereitung

Wenn Sie die digitale Präsentation von Ausweisen testen möchten, müssen Sie sich zuerst mit dem vorgesehenen Testkonto (einem Gmail-Konto) für das öffentliche Betaprogramm registrieren. Stellen Sie Ihrem zuständigen Google-Ansprechpartner die folgenden Informationen zur Verfügung.

  • Link zu den Nutzungsbedingungen
  • Logo
  • Website
  • App-Paket-IDs (für Android-App-Integrationen)
    • Entwickler-/Debug-Builds einschließen
  • App-Signatur
    • $ $ANDROID_SDK/build-tools/$BUILD_TOOLS_VERSION/apksigner verify --print-certs -v $APK
  • Gmail-ID, die für die Teilnahme an der öffentlichen Betaversion verwendet wurde

Unterstützte Anmeldedatenformate

Es gibt mehrere vorgeschlagene Standards, die das Datenformat von digitalen Identitätsdokumenten definieren. Zwei davon haben in der Branche eine hohe Akzeptanz erreicht:

  1. mdocs – definiert durch die ISO.
  2. W3C-Verifiable Credentials – definiert vom W3C.

Der Android Credential Manager unterstützt beide Formate, Google Wallet derzeit jedoch nur auf mdoc basierende digitale Ausweise.

Unterstützte Anmeldedaten

Google Wallet unterstützt zwei Arten von Anmeldedaten:

  1. Digitaler Führerschein (Mobile Driver's License, mDL)
  2. Ausweispapier

Sie können beide Anmeldedaten in Ihrem Ablauf mit einer einzigen Parameteränderung anfordern.

Nutzererfahrung

In diesem Abschnitt wird der empfohlene Ablauf für Onlinepräsentationen beschrieben. Im Ablauf wird die Altersangabe für eine App für die Lieferung von Alkohol gezeigt. Die Benutzeroberfläche ist jedoch für das Web und andere Arten von Präsentationen ähnlich.

Nutzer wird aufgefordert, das Alter in der App oder auf der Website zu bestätigen Nutzer sieht verfügbare infrage kommende Anmeldedaten Der Nutzer sieht eine Bestätigungsseite in Google Wallet. Nutzer authentifiziert sich, um die Freigabe zu bestätigen An App oder Website gesendete Daten
Nutzer wird aufgefordert, das Alter in der App oder auf der Website zu bestätigen Nutzer sieht verfügbare infrage kommende Anmeldedaten Der Nutzer sieht eine Bestätigungsseite in Google Wallet. Nutzer authentifiziert sich, um die Freigabe zu bestätigen An App oder Website gesendete Daten

Wichtige Hinweise

  1. Die App oder Website kann den Einstiegspunkt für die API flexibel gestalten. Wie in Schritt 1 gezeigt, empfehlen wir, eine allgemeine Schaltfläche wie „Mit digitalem Ausweis bestätigen“ anzuzeigen, da wir davon ausgehen, dass im Laufe der Zeit über die API auch andere Optionen als Google Wallet verfügbar sein werden.
  2. Der Auswahlbildschirm in Schritt 2 wird von Android gerendert. Die infrage kommenden Anmeldedaten werden durch einen Abgleich zwischen der von jeder Wallet bereitgestellten Registrierungslogik und der von der vertrauenden Partei gesendeten Anfrage bestimmt.
  3. Schritt 3 wird von Google Wallet gerendert. In Google Wallet werden auf diesem Bildschirm der Name, das Logo und die Datenschutzerklärung angezeigt, die der Entwickler bereitstellt.

Ablauf für digitalen Ausweis hinzufügen

Wenn der Nutzer keine Anmeldedaten hat, empfehlen wir, neben der Schaltfläche „Mit digitalem Ausweis bestätigen“ einen Link bereitzustellen, der einen Deeplink zu Google Wallet enthält, damit der Nutzer einen digitalen Ausweis hinzufügen kann.

Nutzer wird aufgefordert, das Alter in der App oder auf der Website zu bestätigen Nutzer werden zu Google Wallet weitergeleitet, um einen digitalen Ausweis zu erhalten
Nutzer wird aufgefordert, das Alter in der App oder auf der Website zu bestätigen Nutzer werden zu Google Wallet weitergeleitet, um einen digitalen Ausweis zu erhalten

Kein digitaler amtlicher Ausweis verfügbar

Wenn der Nutzer die Option „Mit digitaler ID bestätigen“ auswählt, ohne eine digitale ID zu haben, wird diese Fehlermeldung angezeigt.

Nutzer wird aufgefordert, das Alter in der App oder auf der Website zu bestätigen Nutzer sehen eine Fehlermeldung, wenn sie keine digitale ID haben
Nutzer wird aufgefordert, das Alter in der App oder auf der Website zu bestätigen Nutzer sehen eine Fehlermeldung, wenn sie keine digitale ID haben

Die API unterstützt keine Funktion, mit der unbemerkt ermittelt werden kann, ob der Nutzer digitale IDs hat, um die Privatsphäre des Nutzers zu schützen. Wir empfehlen daher, die Option für den Onboarding-Link wie gezeigt einzufügen.

Anfrageformat zum Anfordern von Ausweisanmeldedaten aus dem Wallet

Hier ist ein Beispiel für eine requestJson-Anfrage für ein mobiles Dokument, um Identitätsanmeldedaten von einem beliebigen Wallet auf einem Android-Gerät oder im Web abzurufen.

{
      "requests" : [
        {
          "protocol": "openid4vp",
          "data": {<credential_request>} // This is an object, shouldn't be a string.
        }
      ]
}

Verschlüsselung anfordern

Der client_metadata enthält den öffentlichen Verschlüsselungsschlüssel für jede Anfrage. Sie müssen private Schlüssel für jede Anfrage speichern und damit das Token authentifizieren und autorisieren, das Sie von der Wallet App erhalten.

Der Parameter credential_request in requestJson würde die folgenden Felder enthalten.

{
  "response_type": "vp_token",
  "response_mode": "dc_api.jwt",
  "nonce": "1234",
  "dcql_query": {
    "credentials": [
      {
        "id": "cred1",
        "format": "mso_mdoc",
        "meta": {
          "doctype_value": "org.iso.18013.5.1.mDL"  // this is for mDL. Use com.google.wallet.idcard.1 for ID pass
        },
        "claims": [
          {
            "path": [
              "org.iso.18013.5.1",
              "family_name"
            ],
            "intent_to_retain": false // set this to true if you are saving the value of the field
          },
          {
            "path": [
              "org.iso.18013.5.1",
              "given_name"
            ],
            "intent_to_retain": false
          },
          {
            "path": [
              "org.iso.18013.5.1",
              "age_over_18"
            ],
            "intent_to_retain": false
          }
        ]
      }
    ]
  },
  "client_metadata": {
    "jwks": {
      "keys": [ // sample request encryption key
        {
          "kty": "EC",
          "crv": "P-256",
          "x": "pDe667JupOe9pXc8xQyf_H03jsQu24r5qXI25x_n1Zs",
          "y": "w-g0OrRBN7WFLX3zsngfCWD3zfor5-NLHxJPmzsSvqQ",
          "use": "enc",
          "kid" : "1",
          "alg" : "ECDH-ES",
        }
      ]
    },
    "authorization_encrypted_response_alg": "ECDH-ES",
    "authorization_encrypted_response_enc": "A128GCM"
  }
}

Sie können eine beliebige Anzahl von unterstützten Attributen aus allen in Google Wallet gespeicherten Ausweisen anfordern.

In-App

So fordern Sie Identitätsanmeldedaten von Ihren Android-Apps an:

Abhängigkeiten aktualisieren

Aktualisieren Sie in der Datei „build.gradle“ Ihres Projekts die Abhängigkeiten, um Credential Manager (Beta) zu verwenden:

dependencies {
    implementation("androidx.credentials:credentials:1.5.0-beta01")
    // optional - needed for credentials support from play services, for devices running Android 13 and below.
    implementation("androidx.credentials:credentials-play-services-auth:1.5.0-beta01")
}

Credential Manager konfigurieren

Fügen Sie zum Konfigurieren und Initialisieren eines CredentialManager-Objekts eine Logik hinzu, die der folgenden ähnelt:

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

Attribute zur Identität anfordern

Anstatt einzelne Parameter für Identitätsanfragen anzugeben, stellt die App sie alle zusammen als JSON-String in der CredentialOption bereit. Der Credential Manager übergibt diesen JSON-String an die verfügbaren digitalen Wallets, ohne seinen Inhalt zu prüfen. Jede Wallet ist dann für Folgendes verantwortlich: - Parsen des JSON-Strings, um die Identitätsanfrage zu verstehen. – Ermitteln, welche der gespeicherten Anmeldedaten die Anfrage erfüllen.

Wir empfehlen Partnern, ihre Anfragen auch für Android-App-Integrationen auf dem Server zu erstellen.

Sie verwenden die requestJson aus Anfrageformat, die aus dem request im GetDigitalCredentialOption()-Funktionsaufruf besteht.

// The request in the JSON format to conform with
// the JSON-ified Digital Credentials API request definition.
val requestJson = generateRequestFromServer()
val digitalCredentialOption =
    GetDigitalCredentialOption(requestJson = requestJson)

// Use the option from the previous step to build the `GetCredentialRequest`.
val getCredRequest = GetCredentialRequest(
    listOf(digitalCredentialOption)
)

coroutineScope.launch {
    try {
        val result = credentialManager.getCredential(
            context = activityContext,
            request = getCredRequest
        )
        verifyResult(result)
    } catch (e : GetCredentialException) {
        handleFailure(e)
    }
}

Antwort überprüfen und validieren

Sobald Sie eine Antwort vom Wallet erhalten haben, prüfen Sie, ob die Antwort erfolgreich ist und die credentialJson-Antwort enthält.

// Handle the successfully returned credential.
fun verifyResult(result: GetCredentialResponse) {
    val credential = result.credential
    when (credential) {
        is DigitalCredential -> {
            val responseJson = credential.credentialJson
            validateResponseOnServer(responseJson) // make a server call to validate the response
        }
        else -> {
            // Catch any unrecognized credential type here.
            Log.e(TAG, "Unexpected type of credential ${credential.type}")
        }
    }
}

// Handle failure.
fun handleFailure(e: GetCredentialException) {
  when (e) {
        is GetCredentialCancellationException -> {
            // The user intentionally canceled the operation and chose not
            // to share the credential.
        }
        is GetCredentialInterruptedException -> {
            // Retry-able error. Consider retrying the call.
        }
        is NoCredentialException -> {
            // No credential was available.
        }
        else -> Log.w(TAG, "Unexpected exception type ${e::class.java}")
    }
}

Die credentialJson-Antwort enthält ein verschlüsseltes identityToken (JWT), das vom W3C definiert wird. Die Wallet App ist für die Erstellung dieser Antwort verantwortlich.

Beispiel:

{
  "protocol" : "openid4vp",
  "data" : {
    <encrpted_response>
  }
}

Sie geben diese Antwort an den Server zurück, um ihre Authentizität zu bestätigen. Hier finden Sie eine Anleitung zum Validieren der Anmeldedatenantwort.

Web

Wenn Sie Identitätsanmeldedaten über die Digital Credentials API in Chrome anfordern möchten, müssen Sie sich für den Ursprungstest der Digital Credentials API registrieren.

const credentialResponse = await navigator.credentials.get({
          digital : {
          requests : [
            {
              protocol: "openid4vp",
              data: {<credential_request>} // This is an object, shouldn't be a string.
            }
          ]
        }
      })

Senden Sie die Antwort von dieser API zurück an Ihren Server, um die Anmeldedatenantwort zu validieren.

Schritte zum Validieren der Anmeldedatenantwort

Nachdem Sie das verschlüsselte identityToken von Ihrer App oder Website erhalten haben, müssen Sie mehrere Validierungen durchführen, bevor Sie der Antwort vertrauen können.

  1. Antwort mit privatem Schlüssel entschlüsseln

    Im ersten Schritt wird das Token mit dem gespeicherten privaten Schlüssel entschlüsselt und ein JSON-Antwortobjekt abgerufen.

    Python-Beispiel:

    from jwcrypto import jwe, jwk
    
    # Retrieve the Private Key from Datastore
    reader_private_jwk = jwk.JWK.from_json(jwe_private_key_json_str)
    
    # Decrypt the JWE encrypted response from Google Wallet
    jwe_object = jwe.JWE()
    jwe_object.deserialize(encrypted_jwe_response_from_wallet)
    jwe_object.decrypt(reader_private_jwk)
    decrypted_payload_bytes = jwe_object.payload
    decrypted_data = json.loads(decrypted_payload_bytes)
    

    decrypted_data führt zu einer vp_token-JSON-Datei mit den Anmeldedaten.

    {
      "vp_token":
      {
        "cred1": "<credential_token>"
      }
    }
    
  2. Sitzungstranskript erstellen

    Als Nächstes erstellen Sie das SessionTranscript aus ISO/IEC 18013-5:2021 mit einer Android- oder webspezifischen Übergabestruktur:

    SessionTranscript = [
      null,                // DeviceEngagementBytes not available
      null,                // EReaderKeyBytes not available
      [
        "OpenID4VPDCAPIHandover",
        AndroidHandoverDataBytes   // BrowserHandoverDataBytes for Web
      ]
    ]
    

    Für beide Arten von Übergaben (Android / Web) müssen Sie dieselbe Nonce verwenden, mit der Sie credential_request generiert haben.

    Android-Übergabe

        AndroidHandoverData = [
          origin,             // "android:apk-key-hash:<base64SHA256_ofAppSigningCert>",
          clientId,           // "android-origin:<app_package_name>",
          nonce,              // nonce that was used to generate credential request
        ]
    
        AndroidHandoverDataBytes = hashlib.sha256(cbor2.dumps(AndroidHandoverData)).digest()
        

    Browserübergabe

        BrowserHandoverData =[
          origin,               // Origin URL
          clientId,             // "web-origin:<origin>"
          nonce,               //  nonce that was used to generate credential request
        ]
    
        BrowserHandoverDataBytes = hashlib.sha256(cbor2.dumps(BrowserHandoverData)).digest()
        

    Bei Verwendung von SessionTranscript muss die DeviceResponse gemäß ISO/IEC 18013-5:2021, Abschnitt 9, validiert werden. Dazu sind mehrere Schritte erforderlich, z. B.:

  3. Prüfen Sie das Zertifikat des Ausstellers des Bundesstaats. IACA-Zertifikate des unterstützten Ausstellers ansehen

  4. MSO-Signatur überprüfen (18013-5, Abschnitt 9.1.2)

  5. ValueDigests für Datenelemente berechnen und prüfen (18013-5, Abschnitt 9.1.2)

  6. Signatur von deviceSignature überprüfen (18013-5, Abschnitt 9.1.3)

{
  "version": "1.0",
  "documents": [
    {
      "docType": "org.iso.18013.5.1.mDL",
      "issuerSigned": {
        "nameSpaces": {...}, // contains data elements
        "issuerAuth": [...]  // COSE_Sign1 w/ issuer PK, mso + sig
      },
      "deviceSigned": {
        "nameSpaces": 24(<< {} >>), // empty
        "deviceAuth": {
          "deviceSignature": [...] // COSE_Sign1 w/ device signature
        }
      }
    }
  ],
  "status": 0
}

Lösung testen

Erstelle zum Testen deiner Lösung die Android-App für den Open-Source-Referenzinhaber und führe sie aus. So erstellen und führen Sie die Referenzinhaber-App aus:

  • Klonen Sie das Repository der Referenz-Apps.
  • Öffne das Projekt in Android Studio.
  • Erstelle das Ziel appholder auf deinem Android-Gerät oder Emulator und führe es aus.

Auf Zero-Knowledge-Beweisen (ZKP) basierende Bestätigung

Der Zero-Knowledge-Beweis (ZKP) ist eine kryptografische Methode, mit der eine Person (der Beweiser) einem Prüfer beweisen kann, dass sie bestimmte Identitätsinformationen besitzt oder ein bestimmtes Kriterium erfüllt (z.B. volljährig ist oder einen gültigen Ausweis besitzt), ohne die tatsächlichen zugrunde liegenden Daten preiszugeben. Im Grunde ist es eine Möglichkeit, die Richtigkeit einer Aussage über die eigene Identität zu bestätigen, ohne sensible Details preiszugeben.

Digitale Identitätssysteme, die auf der direkten Weitergabe von Identitätsdaten beruhen, erfordern oft, dass Nutzer übermäßig viele personenbezogene Daten weitergeben, was das Risiko von Datenpannen und Identitätsdiebstahl erhöht. ZKPs stellen einen Paradigmenwechsel dar, der die Überprüfung mit minimaler Offenlegung ermöglicht.

Wichtige Konzepte von ZKPs in der digitalen Identität:

  • Beweiser: Die Person, die versucht, einen Aspekt ihrer Identität zu beweisen.
  • Prüfer: Die Organisation, die einen Nachweis für ein Identitätsattribut anfordert.
  • Der Beweis: Ein kryptografisches Protokoll, mit dem der Beweiser den Prüfer von der Richtigkeit seiner Behauptung überzeugen kann, ohne die geheimen Informationen offenzulegen.

Haupteigenschaften von Zero-Knowledge-Beweisen:

  • Vollständigkeit: Wenn die Aussage wahr ist und sowohl der Beweiser als auch der Prüfer ehrlich sind, wird der Prüfer überzeugt sein.
  • Fundiertheit: Wenn die Aussage falsch ist, kann ein unehrlicher Beweiser einen ehrlichen Prüfer nicht (mit sehr hoher Wahrscheinlichkeit) davon überzeugen, dass sie wahr ist.
  • Zero-Knowledge: Der Prüfer erfährt nichts außer der Tatsache, dass die Aussage wahr ist. Es werden keine tatsächlichen Daten zur Identität des Provers offengelegt.

Wenn Sie einen Zero-Knowledge-Beweis von Google Wallet erhalten möchten, müssen Sie das Anfrageformat in mso_mdoc_zk ändern und zk_system_type zu Ihrer Anfrage hinzufügen.

  ...
  "dcql_query": {
    "credentials": [{
      "id": "cred1",
      "format": "mso_mdoc_zk",
      "meta": {
        "doctype_value": "org.iso.18013.5.1.mDL"
        "zk_system_type": [
        {
          "system": "longfellow-libzk-v1",
          "circuit_hash": "bd3168ea0a9096b4f7b9b61d1c210dac1b7126a9ec40b8bc770d4d485efce4e9", // This will differ if you need more than 1 attribute.
          "num_attributes": 1, // number of attributes (in claims) this has can support
          "version": 3
        },
        {
          "system": "longfellow-libzk-v1",
          "circuit_hash": "89288b9aa69d2120d211618fcca8345deb4f85d2e710c220cc9c059bbee4c91f", // This will differ if you need more than 1 attribute.
          "num_attributes": 1, // number of attributes (in claims) this has can support
          "version": 4
        }
       ],
       "verifier_message": "challenge"
      },
     "claims": [{
         ...
      "client_metadata": {
        "jwks": {
          "keys": [ // sample request encryption key
            {
              ...

Sie erhalten einen verschlüsselten Zero-Knowledge-Beweis vom Wallet zurück. Sie können diesen Nachweis anhand der IACA-Zertifikate der Aussteller mit der longfellow-zk-Bibliothek von Google validieren. Weitere Informationen erhalten Sie unter der Support-E-Mail-Adresse wallet-identity-rp-support@google.com.