Persönliche Akzeptanz digitaler Anmeldedaten (offline)

In diesem Leitfaden wird erläutert, wie vertrauende Seiten und Entwickler von Lesegeräten die persönliche (Offline-)Überprüfung von digitalen Ausweisen, die in Google Wallet vorgelegt werden, gemäß dem internationalen Standard ISO/IEC 18013-5 implementieren können.

Digitale Berechtigungsnachweise in Google Wallet können in physischen Umgebungen (z. B. an POS-Terminals, Veranstaltungsorten, Fahrkartenschranken, Lesegeräten von Strafverfolgungsbehörden und mobilen Lese-Apps) sicher überprüft werden, ohne dass zum Zeitpunkt der Vorlage eine aktive Internetverbindung erforderlich ist.

Übersicht über die Offline-Präsentation (ISO/IEC 18013-5)

Der Standard ISO/IEC 18013-5 definiert ein standardisiertes, interoperables Protokoll für die Offline-Präsentation zwischen einem Inhaber (dem Mobilgerät des Nutzers, auf dem Google Wallet ausgeführt wird) und einem Lesegerät / Prüfer (einem physischen Terminal oder einer Companion-App).

Der Präsentationsablauf erfolgt in verschiedenen Phasen:

  1. Geräteinteraktion: Das Lesegerät und Wallet stellen den ersten Kontakt über NFC-Tippen (statische oder ausgehandelte Übergabe) oder QR-Code-Scan her. In dieser Phase werden Metadaten zur Geräteinteraktion und der sitzungsspezifische öffentliche Schlüssel des Lesegeräts (EReaderKey) ausgetauscht.
  2. Datentransportverbindung:Es wird ein sicherer, verschlüsselter Bluetooth Low Energy (BLE)-Kanal ausgehandelt, wobei das Lesegerät im Central Client- oder Peripheral Server-Modus agiert.
  3. Geräteanfrage:Das Lesegerät überträgt eine CBOR-codierte DeviceRequest, in der der angeforderte Dokumenttyp (z. B. org.iso.18013.5.1.mDL) sowie die angeforderten Namespaces und Datenelemente angegeben sind.
  4. Nutzereinwilligung und Geräteauthentifizierung: Google Wallet fordert den Nutzer auf, die angeforderten Datenelemente zu prüfen und die Weitergabe per biometrischer Authentifizierung oder Displaysperre zu bestätigen.
  5. Geräteantwort und kryptografische Überprüfung:Das Wallet sendet eine CBOR-codierte DeviceResponse zurück, die das signierte Mobile Security Object (MSO) und vom Gerät signierte Datenelemente enthält. Das Lesegerät verifiziert die kryptografischen Signaturen anhand vertrauenswürdiger Root-Zertifikate.

Das Multipaz Open-Source SDK

Für die Implementierung einer Lesegerät- oder Prüf-App empfiehlt Google die Verwendung von Multipaz, einem Open-Source-Kotlin-Multiplatform-SDK (KMP), das ursprünglich von Google entwickelt und der OpenWallet Foundation (OWF) zur Verfügung gestellt wurde.

Multipaz bietet eine produktionsreife Implementierung von ISO/IEC 18013-5-Lesegerät- und Wallet-Protokollen, kryptografischen Verifizierungspipelines, CBOR-Codierung/-Decodierung und erweiterbaren Dokumenttypschemas.

Multipaz in Ihre Lesegerät-App einbinden

In den folgenden Schritten wird gezeigt, wie Sie das Multipaz SDK in eine Android-Lesegerät-App einbinden.

Schritt 1: Abhängigkeiten hinzufügen

Multipaz-Bibliotheken werden auf Maven Central veröffentlicht. Fügen Sie der Datei build.gradle.kts Ihrer Anwendung die erforderlichen Module hinzu:

// build.gradle.kts
dependencies {
    // Core Multipaz library (protocol engine, CBOR, crypto)
    implementation("org.multipaz:multipaz:0.100.0")

    // Android-specific platform bindings (NFC, BLE, Keystore)
    implementation("org.multipaz:multipaz-android:0.100.0")

    // Standardized document types (mDL, EU PID, etc.)
    implementation("org.multipaz:multipaz-doctypes:0.100.0")
}

Schritt 2: Android-Berechtigungen konfigurieren

Für die persönliche Überprüfung sind Hardwareberechtigungen für die NFC-Nutzung, das Scannen mit der Kamera (für die QR-Nutzung) und die Datenübertragung über Bluetooth Low Energy erforderlich. Fügen Sie Ihrer AndroidManifest.xml die folgenden Berechtigungen hinzu:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- NFC Engagement -->
    <uses-permission android:name="android.permission.NFC" />
    <uses-feature android:name="android.hardware.nfc" android:required="false" />

    <!-- Camera for QR Code Engagement -->
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" android:required="false" />

    <!-- Bluetooth Low Energy Transport (Android 12+) -->
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN"
                     android:usesPermissionFlags="neverForLocation" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />

    <!-- Legacy Bluetooth Permissions for Android 11 and lower -->
    <uses-permission android:name="android.permission.BLUETOOTH"
                     android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
                     android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
                     android:maxSdkVersion="30" />
</manifest>

Schritt 3: Verification Engine initialisieren

Verwenden Sie die Multipaz-Abstraktionen VerificationHelper oder Reader-Verbindung, um Engagement-Ereignisse zu verarbeiten und den Lebenszyklus der BLE-Kommunikation zu verwalten:

import org.multipaz.verification.VerificationHelper
import org.multipaz.cbor.Cbor
import org.multipaz.crypto.Crypto

class ReaderManager(private val context: android.content.Context) {

    private var verificationHelper: VerificationHelper? = null

    fun startListeningForEngagement() {
        verificationHelper = VerificationHelper.Builder(
            context = context,
            listener = object : VerificationHelper.Listener {
                override fun onDeviceConnected() {
                    // BLE channel established, send request
                    sendDeviceRequest()
                }

                override fun onResponseReceived(deviceResponseBytes: ByteArray) {
                    // Process and verify the received credential payload
                    handleDeviceResponse(deviceResponseBytes)
                }

                override fun onError(error: Throwable) {
                    // Handle transport or protocol errors
                }

                override fun onDeviceDisconnected(transportTransportSpecificTermination: Boolean) {
                    // Connection closed
                }
            }
        ).build()
    }
}

Schritt 4: DeviceRequest erstellen

Geben Sie den Dokumenttyp und die einzelnen Datenelemente an, die Ihre Anwendung überprüfen muss. Wenden Sie immer das Prinzip der minimalen Offenlegung an (z.B. nur age_over_21 statt des vollständigen birth_date bei der Altersbestätigung anfordern):

fun sendDeviceRequest() {
    // Specify the DocType and requested elements
    val docType = "org.iso.18013.5.1.mDL"
    val namespace = "org.iso.18013.5.1"

    // Map of requested elements: elementName -> intentToRetain
    val requestedElements = mapOf(
        "family_name" to false,
        "given_name" to false,
        "age_over_21" to false,
        "portrait" to false,
        "driving_privileges" to false
    )

    // Build ISO/IEC 18013-5 DeviceRequest structure
    val deviceRequestBytes = verificationHelper?.buildDeviceRequest(
        docType = docType,
        itemsToRequest = mapOf(namespace to requestedElements)
    )

    if (deviceRequestBytes != null) {
        verificationHelper?.sendDeviceRequest(deviceRequestBytes)
    }
}

Unterstützung zusätzlicher Dokumenttypen (DocTypes)

Multipaz unterstützt standardisierte Ausweise und bietet eine erweiterbare Architektur, um benutzerdefinierte oder domainspezifische Dokumenttypen anzufordern.

1. Integrierte Standarddokumenttypen

Die multipaz-doctypes-Bibliothek bietet vordefinierte Schemamodelle für Standardanmeldedaten:

Dokumenttyp-ID Standard / Umfang Typischer Namespace Gemeinsame Elemente
org.iso.18013.5.1.mDL ISO/IEC 18013-5 – Digitaler Führerschein org.iso.18013.5.1 family_name, given_name, birth_date, issue_date, expiry_date, issuing_authority, document_number, portrait, driving_privileges, age_over_18, age_over_21
eu.europa.ec.eudi.pid.1 Personenidentifikationsdaten der EU-Brieftasche für die digitale Identität (EUDIW) eu.europa.ec.eudi.pid.1 family_name, first_name, birth_date, nationality, issuing_country, issuing_authority, personal_administrative_number
com.google.wallet.idcard.1 Google Wallet-ID-Karte / Test-IDs com.google.wallet.idcard.1 given_name, family_name, birth_date, document_number, portrait

2. Benutzerdefinierte Dokumenttypen anfordern

Wenn Sie benutzerdefinierte Dokumenttypen anfordern möchten, definieren Sie beim Erstellen der DeviceRequest den Zielstring docType und die entsprechenden Namespace-Zuordnungen:

// Example: Requesting a custom event ticket credential
val customDocType = "com.example.events.ticket"
val customNamespace = "com.example.events.ticket.1"

val customRequestedItems = mapOf(
    "ticket_id" to false,
    "event_name" to false,
    "seat_section" to false,
    "vip_access" to false
)

val multiDocRequestBytes = verificationHelper?.buildMultiDocDeviceRequest(
    documents = listOf(
        DocumentRequest(
            docType = customDocType,
            namespaces = mapOf(customNamespace to customRequestedItems)
        )
    )
)

Kryptografische Überprüfung und Vertrauensverwaltung

Der Empfang einer Antwortnutzlast ist nur der erste Schritt. Lesegeräte müssen eine vierstufige kryptografische Überprüfung durchführen, um die Echtheit und Integrität des vorgelegten Berechtigungsnachweises zu bestätigen.

Bestätigungsschritt Überprüfungsziel
1. Ausstellerauthentifizierung IssuerAuth (COSE_Sign1) mit vertrauenswürdigen IACA-Root-Zertifikaten vergleichen
2. Gültigkeitszeitraum prüfen Achten Sie darauf, dass validFrom ≤ aktuelle Zeit ≤ validUntil ist.
3. Datenintegritätsprüfung SHA-256-Digests der zurückgegebenen Elemente berechnen und mit MSO ValueDigests abgleichen
4. Geräteauthentifizierung DeviceSigned-Signatur oder MAC mit dem an die SessionTranscript gebundenen DeviceKey prüfen

1. Die 4-stufige Verifizierungspipeline

  1. Ausstellerauthentifizierung (IssuerAuth):
    • Das Mobile Security Object (MSO) wird von der ausstellenden Behörde signiert (IssuerAuth-Nutzlast).
    • Das Lesegerät verifiziert die COSE_Sign1-Signatur mithilfe des Document Signer-Zertifikats und stellt sicher, dass die Zertifikatskette bis zu einem vertrauenswürdigen Root-Zertifikat der Issuing Authority CA (IACA) reicht.
  2. Überprüfung des Gültigkeitszeitraums:
    • Das Lesegerät vergleicht die Zeitstempel validityInfo.validFrom und validityInfo.validUntil im MSO mit der aktuellen Uhrzeit des Lesegeräts, um sicherzustellen, dass der Berechtigungsnachweis nicht abgelaufen ist.
  3. Überprüfung der Datenintegrität (ValueDigests):
    • Für jedes empfangene IssuerSignedItem berechnet das Lesegerät den Digest (z.B. SHA-256) und prüft, ob er mit dem entsprechenden Hash-Eintrag im ValueDigests-Wörterbuch des MSO übereinstimmt.
  4. Geräteauthentifizierung (DeviceSigned):
    • Das Lesegerät prüft, ob das Gerät, das den Berechtigungsnachweis vorlegt, den privaten Schlüssel hat, der dem im signierten MSO veröffentlichten DeviceKey entspricht.
    • Dazu wird der DeviceAuth (entweder DeviceSignature oder DeviceMac) über den SessionTranscript verifiziert, die Sitzung an den sitzungsspezifischen Schlüssel des Lesegeräts gebunden und Replay- und Man-in-the-Middle-Angriffe verhindert.

2. Vertrauenswürdige IACA-Root-Zertifikate verwalten

Produktionslesegeräte müssen einen sicheren, lokalen Trust Store mit vertrauenswürdigen IACA-Root-Zertifikaten enthalten:

  • Produktions-IACA-Zertifikate:Laden Sie Root-Zertifikate von offiziellen Ausstellungsstellen herunter und konfigurieren Sie sie. Weitere Informationen finden Sie in der Liste Unterstützte Aussteller und IACA-Zertifikate.
  • AAMVA VICAL:In den USA können Lesesysteme in den VICAL-Dienst (Verified Issuer Certificate Authority List) der American Association of Motor Vehicle Administrators (AAMVA) eingebunden werden, um die Trust-Anchor der Bundesstaaten automatisch zu synchronisieren.
  • Sandbox-Test-Roots: Wenn du mit Sandbox-Anmeldedaten testest, muss das Lesegerät der Google Sandbox IACA Root vertrauen.
import org.multipaz.crypto.X509Cert

// Configure trusted IACA certificates in the trust store
val trustedCertificates = mutableListOf<X509Cert>()

// Add official state IACA certificates
trustedCertificates.add(X509Cert.fromPem(sampleStateIacaPem))

// Add Google Sandbox IACA root certificate for testing
trustedCertificates.add(X509Cert.fromPem(googleSandboxIacaPem))

val verifier = MultipazVerifier(trustStore = trustedCertificates)
val verificationResult = verifier.verify(deviceResponseBytes, sessionTranscript)

if (verificationResult.isIssuerAuthorized && verificationResult.isDeviceAuthenticated) {
    // Credential is valid and authentic
} else {
    // Reject presentation: cryptographic validation failed
}

Leserauthentifizierung (empfohlen)

Mit der Leserauthentifizierung kann die Leser-App ihre Identität gegenüber Google Wallet kryptografisch nachweisen, indem sie die ReaderAuthentication-Struktur mit einem autorisierten X.509-Leserzertifikat signiert.

  • Warum es empfohlen wird: Mit der Leserauthentifizierung kann Ihre Leser-App oder Ihr Terminal dem Nutzer eine vertrauenswürdige Identität präsentieren. Für grundlegende öffentliche Attribute (z. B. die Bestätigung von age_over_21) ist dies optional, wird aber für Lesegerät-Integrationen dringend empfohlen, um das Vertrauen der Nutzer zu stärken. Bei der Abfrage sensibler Attribute (z. B. der vollständigen Sozialversicherungsnummer, der Wohnadresse oder bestimmter staatlicher Bestätigungen) kann dies gesetzlich oder durch Richtlinien vorgeschrieben sein.
  • So funktioniert es: Das Lesegerät fügt seine Zertifikatskette hinzu und signiert das Sitzungstranskript. Google Wallet zeigt dem Nutzer vor der Datenfreigabe auf dem Zustimmungsbildschirm die bestätigte Identität und den Namen der Organisation des Lesegeräts an.

Test- und Entwicklungstools

Verwenden Sie die folgenden Entwicklertools und Referenzimplementierungen, um die Integration zu beschleunigen:

  1. Multipaz-Referenz-Apps:
    • Klonen Sie das Multipaz-Repository und führen Sie die Android-Beispiel-App IdentityReader aus, um die Abläufe für die physische Überprüfung zu testen.
  2. Test-ID in Google Wallet erstellen:
  3. Webbasierte Verifizierungstests:
    • Mit verifier.multipaz.org können Sie CBOR-Anfragen prüfen, Anspruchsabfragen untersuchen und webbasierte Präsentationen nach W3C / ISO 18013-7 testen.

Fehlerbehebung und Diagnose vor Ort

In der folgenden Tabelle sind häufige Probleme bei der Offlinebestätigung und empfohlene Lösungen aufgeführt:

Problem / Symptom Ursache Empfohlene Lösung
Zeitüberschreitung der BLE-Verbindung / Verbindungsfehler
  • HF-Interferenzen in Umgebungen mit hoher Dichte.
  • Inkompatibilität zwischen Peripherie- und Zentralmodus auf bestimmter Lesegerätehardware.
  • Zeitüberschreitungen beim Scannen.
  • Das Lesegerät muss sowohl den BLE-Central-Client- als auch den Peripheral-Server-Modus unterstützen.
  • BLE-Scanfenster und -intervall für aggressives Scannen während der aktiven Nutzung anpassen.
  • Prüfen Sie, ob die MTU-Größenverhandlung erfolgreich abgeschlossen wurde.
NFC-Funktion schlägt fehl oder wird abgebrochen Der Nutzer entfernt das Mobilgerät von der Antenne des Lesegeräts, bevor der BLE-Übergabedatensatz vollständig übertragen wurde.
  • Sobald die NFC-Interaktion beginnt, muss das Terminal sofort visuelles, akustisches oder haptisches Feedback geben.
  • Weise die Nutzer an, das Smartphone ruhig an das NFC-Ziel zu halten, bis die BLE-Verbindung hergestellt ist.
UNTRUSTED_ISSUER / Fehler bei der Zertifikatskette Das Zertifikat des Dokumentenunterzeichners ist nicht mit einem vertrauenswürdigen IACA-Zertifikat im lokalen Trust Store des Lesegeräts verknüpft.
  • Prüfen Sie, ob das Root-Zertifikat des Ausstellers in den Trust Store des Lesegeräts geladen wurde.
  • Wenn Sie in der Sandbox testen, prüfen Sie, ob die Google Sandbox IACA Root geladen ist.
  • Achten Sie darauf, dass IACA-Zertifikatslisten (z.B. AAMVA VICAL) regelmäßig aktualisiert werden.
INVALID_VALIDITY_INFO / Abgelaufenes MSO
  • Die Systemuhr des Lesegeräts ist nicht synchronisiert.
  • Die MSO-Signatur ist abgelaufen.
  • Achten Sie darauf, dass das Lesegerät seine Systemzeit regelmäßig über NTP synchronisiert.
  • Fordere den Nutzer auf, Google Wallet zu öffnen, während er mit dem Internet verbunden ist, um die Berechtigungs-Tokens zu aktualisieren.
DEVICE_AUTHENTICATION_FAILED Das Sitzungstranskript zwischen Lesegerät und Wallet stimmt nicht überein oder die temporäre Gerätesignatur ist ungültig.
  • Achten Sie darauf, dass die genauen Rohbyte von DeviceEngagementBytes und EReaderKeyBytes in der SessionTranscript-Struktur ohne Neucodierung beibehalten werden.
Absturz aufgrund von Berechtigungen unter Android 12 und höher Die Anwendung hat versucht, ohne Laufzeitberechtigungen über BLE zu scannen oder zu werben.
  • Prüfen und fordern Sie BLUETOOTH_SCAN, BLUETOOTH_CONNECT und BLUETOOTH_ADVERTISE zur Laufzeit an, bevor Sie Lesesitzungen starten.

UX- und Datenschutzrichtlinien für Lesegeräte für den persönlichen Gebrauch

Beim Entwerfen von physischen Lesegeräten und Companion-Apps:

  • Selektive Offenlegung in der Benutzeroberfläche:Zeigen Sie dem Betreiber nur die Entscheidung oder das mindestens erforderliche Attribut an (z.B. ein auffälliges grünes Häkchen und „Alter 21+ bestätigt“ anstelle des vollständigen Geburtsdatums, der Adresse und der Führerscheinnummer des Nutzers).
  • Klare Indikatoren für die physische Interaktion:Kennzeichnen Sie den NFC-Zielbereich deutlich und zeigen Sie visuelle Hinweise (z. B. Animationen oder Fortschrittsanzeigen) für jede Phase an: Tippen / Scannen → Verbinden → Verifizieren → Abgeschlossen.
  • Umgang mit flüchtigen Daten:Speichere oder protokolliere keine personenbezogenen Daten, die du von der Wallet erhältst, es sei denn, dies ist ausdrücklich durch geltendes Recht vorgeschrieben und wird über intentToRetain = true offengelegt.