Panduan ini menjelaskan cara Pihak Pengandalkan (RP) dan developer pembaca dapat menerapkan verifikasi langsung (offline) kredensial digital yang ditampilkan dari Google Wallet sesuai dengan standar internasional ISO/IEC 18013-5.
Kredensial digital di Google Wallet dapat diverifikasi dengan aman di lingkungan fisik (seperti terminal tempat penjualan, tempat acara, gerbang transportasi umum, pembaca penegak hukum, dan aplikasi pembaca seluler) tanpa memerlukan koneksi internet aktif pada saat presentasi.
Ringkasan Presentasi Offline (ISO/IEC 18013-5)
Standar ISO/IEC 18013-5 menentukan protokol standar yang dapat dioperasikan untuk presentasi offline antara Pemegang (perangkat seluler pengguna yang menjalankan Google Wallet) dan Pembaca / Pemverifikasi (terminal fisik atau aplikasi seluler pendamping).
Alur presentasi terjadi dalam beberapa fase yang berbeda:
- Interaksi Perangkat: Pembaca dan dompet membuat kontak awal melalui Ketukan NFC (Handover Statis atau yang Dinegosiasikan) atau pemindaian Kode QR. Selama fase ini, metadata interaksi perangkat dan kunci publik sementara pembaca (
EReaderKey) akan dipertukarkan. - Koneksi Transportasi Data: Saluran Bluetooth Hemat Energi (BLE) yang aman dan terenkripsi dinegosiasikan (dengan pembaca yang bertindak dalam mode Klien Pusat atau Server Periferal).
- Permintaan Perangkat: Pembaca mengirimkan
DeviceRequestyang dienkode CBOR yang menentukan jenis dokumen yang diminta (sepertiorg.iso.18013.5.1.mDL) serta namespace dan elemen data tertentu yang diminta. - Izin Pengguna & Autentikasi Perangkat: Google Wallet meminta pengguna untuk meninjau elemen data yang diminta dan mengonfirmasi pembagian menggunakan autentikasi biometrik atau kunci layar.
- Respons Perangkat & Verifikasi Kriptografis: Dompet mengirimkan kembali
DeviceResponseyang dienkode CBOR yang berisi Mobile Security Object (MSO) yang ditandatangani dan elemen data yang ditandatangani perangkat. Pembaca memverifikasi tanda tangan kriptografis berdasarkan root certificate tepercaya.
Multipaz Open-Source SDK
Untuk mengimplementasikan aplikasi pembaca atau pemverifikasi, Google merekomendasikan penggunaan Multipaz, SDK Kotlin Multiplatform (KMP) open source yang awalnya dikembangkan oleh Google dan dikontribusikan ke OpenWallet Foundation (OWF).
Multipaz menyediakan implementasi protokol dompet dan pembaca ISO/IEC 18013-5 yang siap produksi, pipeline verifikasi kriptografis, encoding/dekode CBOR, dan skema jenis dokumen yang dapat diperluas.
Mengintegrasikan Multipaz ke Aplikasi Pembaca Anda
Langkah-langkah berikut menunjukkan cara mengintegrasikan Multipaz SDK ke dalam aplikasi pembaca Android.
Langkah 1: Tambahkan Dependensi
Library Multipaz dipublikasikan di Maven Central. Tambahkan modul yang diperlukan ke file build.gradle.kts aplikasi Anda:
// 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")
}
Langkah 2: Konfigurasikan Izin Android
Verifikasi langsung memerlukan izin hardware untuk interaksi NFC, pemindaian kamera (untuk interaksi QR), dan pengiriman data Bluetooth Hemat Energi. Tambahkan izin berikut ke AndroidManifest.xml Anda:
<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>
Langkah 3: Lakukan inisialisasi Mesin Verifikasi
Gunakan abstraksi koneksi VerificationHelper atau Reader Multipaz untuk menangani peristiwa engagement dan mengelola siklus proses komunikasi BLE:
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()
}
}
Langkah 4: Buat DeviceRequest
Tentukan jenis dokumen dan elemen data individual yang perlu diverifikasi oleh aplikasi Anda. Selalu terapkan prinsip pengungkapan minimal (misalnya, hanya meminta age_over_21, bukan birth_date lengkap saat memverifikasi usia):
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)
}
}
Mendukung Jenis Dokumen (DocType) Tambahan
Multipaz mendukung kredensial standar secara langsung dan menyediakan arsitektur yang dapat diperluas untuk meminta jenis dokumen kustom atau khusus domain.
1. Jenis Dokumen Standar Bawaan
Library multipaz-doctypes menyediakan model skema yang telah ditentukan untuk kredensial standar:
| ID Jenis Dokumen | Standar / Cakupan | Namespace Umum | Elemen Umum |
|---|---|---|---|
org.iso.18013.5.1.mDL |
Surat Izin Mengemudi Digital ISO/IEC 18013-5 | 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 |
Data Identifikasi Orang Dompet Identitas Digital Uni Eropa (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 |
Tanda Pengenal Digital Google Wallet / ID Pengujian | com.google.wallet.idcard.1 |
given_name, family_name, birth_date, document_number, portrait |
2. Meminta Jenis Dokumen Kustom
Untuk meminta jenis dokumen kustom, tentukan string docType target dan pemetaan namespace yang sesuai saat membuat DeviceRequest:
// 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)
)
)
)
Verifikasi Kriptografi & Pengelolaan Trust
Menerima payload respons hanyalah langkah pertama. Pembaca harus melakukan verifikasi kriptografis empat langkah untuk memvalidasi keaslian dan integritas kredensial yang ditampilkan.
| Langkah Verifikasi | Target Verifikasi |
|---|---|
| 1. Autentikasi Penerbit | Memverifikasi IssuerAuth (COSE_Sign1) terhadap root certificate IACA tepercaya |
| 2. Pemeriksaan Periode Validitas | Pastikan validFrom ≤ waktu saat ini ≤ validUntil |
| 3. Pemeriksaan Integritas Data | Menghitung ringkasan SHA-256 dari elemen yang ditampilkan dan mencocokkannya dengan MSO ValueDigests |
| 4. Autentikasi Perangkat | Memverifikasi tanda tangan DeviceSigned atau MAC menggunakan DeviceKey yang terikat ke SessionTranscript |
1. Pipeline Verifikasi 4 Langkah
- Autentikasi Penerbit (
IssuerAuth):- Mobile Security Object (MSO) ditandatangani oleh Otoritas Penerbit (payload
IssuerAuth). - Pembaca memverifikasi tanda tangan
COSE_Sign1menggunakan sertifikat Penanda Tangan Dokumen dan memastikan sertifikat tersebut terhubung ke root certificate Issuing Authority CA (IACA) tepercaya.
- Mobile Security Object (MSO) ditandatangani oleh Otoritas Penerbit (payload
- Verifikasi Jendela Validitas:
- Pembaca memeriksa stempel waktu
validityInfo.validFromdanvalidityInfo.validUntildi MSO terhadap jam pembaca saat ini untuk memastikan kredensial belum habis masa berlakunya.
- Pembaca memeriksa stempel waktu
- Verifikasi Integritas Data (
ValueDigests):- Untuk setiap
IssuerSignedItemyang diterima, pembaca menghitung ringkasannya (misalnya SHA-256) dan memverifikasi bahwa ringkasan tersebut cocok dengan entri hash yang sesuai dalam kamusValueDigestsMSO.
- Untuk setiap
- Autentikasi Perangkat (
DeviceSigned):- Pembaca memvalidasi bahwa perangkat yang menampilkan kredensial memiliki kunci pribadi yang sesuai dengan
DeviceKeyyang dipublikasikan di dalam MSO yang ditandatangani. - Hal ini dilakukan dengan memverifikasi
DeviceAuth(DeviceSignatureatauDeviceMac) melaluiSessionTranscript, mengikat sesi ke kunci sementara pembaca, serta mencegah serangan replay dan man-in-the-middle.
- Pembaca memvalidasi bahwa perangkat yang menampilkan kredensial memiliki kunci pribadi yang sesuai dengan
2. Mengelola Root Certificate IACA Tepercaya
Pembaca produksi harus mengelola trust store lokal yang aman dan berisi root certificate IACA tepercaya:
- Sertifikat IACA Produksi: Download dan konfigurasi root certificate dari otoritas penerbit resmi. Lihat daftar Penerbit dan Sertifikat IACA yang Didukung.
- AAMVA VICAL: Untuk wilayah hukum AS, sistem pembaca dapat berintegrasi dengan layanan Verified Issuer Certificate Authority List (VICAL) American Association of Motor Vehicle Administrators (AAMVA) untuk otomatis menyinkronkan trust anchor negara bagian.
- Root Pengujian Sandbox: Saat menguji kredensial sandbox, pastikan pembaca memercayai Root IACA Sandbox Google.
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
}
Autentikasi Pembaca (Direkomendasikan)
Autentikasi Pembaca memungkinkan aplikasi pembaca membuktikan identitasnya secara kriptografis ke Google Wallet dengan menandatangani struktur ReaderAuthentication menggunakan sertifikat pembaca X.509 yang sah.
- Alasan Direkomendasikan: Autentikasi Pembaca memungkinkan aplikasi atau terminal pembaca Anda menampilkan identitas tepercaya kepada pengguna. Meskipun bersifat opsional untuk atribut publik dasar (misalnya, memverifikasi
age_over_21), langkah ini sangat direkomendasikan untuk integrasi pembaca guna meningkatkan kepercayaan pengguna dan mungkin diwajibkan secara hukum atau kebijakan saat meminta atribut sensitif (seperti Nomor Jaminan Sosial lengkap, alamat tempat tinggal, atau pengesahan negara bagian tertentu). - Cara Kerjanya: Pembaca menyertakan rantai sertifikatnya dan menandatangani transkrip sesi. Google Wallet menampilkan identitas dan nama organisasi pembaca yang terverifikasi kepada pengguna di layar izin sebelum data dirilis.
Alat Pengujian & Pengembangan
Untuk mempercepat integrasi, gunakan alat developer dan implementasi referensi berikut:
- Aplikasi Referensi Multipaz:
- Buat clone repositori Multipaz dan jalankan aplikasi contoh Android
IdentityReaderuntuk menguji alur verifikasi fisik.
- Buat clone repositori Multipaz dan jalankan aplikasi contoh Android
- Membuat Tanda Pengenal Pengujian di Google Wallet:
- Ikuti panduan Membuat Tanda Pengenal Digital Pengujian di Google Wallet untuk menyediakan kredensial pengujian simulasi ke Google Wallet menggunakan Utopia ePassport Simulator.
- Pengujian Verifikasi Berbasis Web:
- Gunakan verifier.multipaz.org untuk memeriksa permintaan CBOR, mempelajari kueri klaim, dan menguji presentasi berbasis web W3C / ISO 18013-7.
Pemecahan Masalah & Diagnostik Lapangan
Tabel berikut mencantumkan masalah umum yang terjadi selama verifikasi offline dan solusi yang direkomendasikan:
| Masalah / Gejala | Penyebab Utama | Resolusi yang Direkomendasikan |
|---|---|---|
| Waktu tunggu koneksi BLE habis / Gagal terhubung |
|
|
| Interaksi ketuk NFC gagal atau terhenti | Pengguna menarik perangkat seluler dari antena pembaca sebelum data pengalihan BLE ditransfer sepenuhnya. |
|
UNTRUSTED_ISSUER / Kegagalan rantai sertifikat |
Sertifikat Document Signer tidak terhubung ke sertifikat IACA tepercaya di trust store lokal pembaca. |
|
INVALID_VALIDITY_INFO / MSO yang Sudah Tidak Berlaku |
|
|
DEVICE_AUTHENTICATION_FAILED |
Transkrip sesi tidak cocok antara pembaca dan dompet, atau tanda tangan perangkat sementara tidak valid. |
|
| Error izin Android 12+ | Aplikasi mencoba memindai atau memberitahukan melalui BLE tanpa izin runtime. |
|
Panduan UX & Privasi untuk Pembaca Langsung
Saat mendesain pembaca fisik dan aplikasi pendamping:
- Terapkan Pengungkapan Selektif di UI: Hanya tampilkan keputusan atau atribut minimum yang diperlukan kepada operator (misalnya, tampilkan tanda centang hijau yang jelas dan "Usia 21+ Terverifikasi", bukan menampilkan tanggal lahir, alamat, dan nomor lisensi lengkap pengguna).
- Indikator Interaksi Fisik yang Jelas: Beri label zona target NFC dengan jelas dan tampilkan petunjuk visual (seperti animasi atau status progres) yang menunjukkan setiap tahap: Ketuk / Pindai → Menghubungkan → Memverifikasi → Selesai.
- Penanganan Data Sementara: Jangan menyimpan atau mencatat elemen data pribadi yang diterima dari dompet, kecuali jika diwajibkan secara eksplisit oleh hukum yang berlaku dan diungkapkan melalui
intentToRetain = true.