Credential Manager Holder API memungkinkan aplikasi pemegang (juga disebut "dompet") Android Anda untuk mengelola dan menampilkan kredensial digital kepada verifier.
Konsep inti
Penting untuk memahami konsep berikut sebelum menggunakan Holder API.
Format kredensial
Kredensial dapat disimpan di aplikasi pemegang dalam format kredensial yang berbeda. Format ini adalah spesifikasi tentang cara kredensial harus ditampilkan, dan setiap format berisi informasi berikut tentang kredensial:
- Jenis: Kategori seperti gelar universitas atau surat izin mengemudi seluler.
- Properti: Atribut seperti nama depan dan belakang.
- Encoding: Cara kredensial disusun, misalnya SD-JWT atau mdoc
- Validitas: Metode untuk memverifikasi keaslian kredensial secara kriptografis.
Setiap format kredensial melakukan encoding dan validasi dengan sedikit berbeda, tetapi secara fungsional, keduanya sama.
Registri mendukung dua format:
- SD-JWT: sesuai dengan spesifikasi IETF SD-JWT-based Verifiable Credentials (SD-JWT VC).
- Dokumen Seluler atau mdocs: sesuai dengan spesifikasi ISO/IEC 18013-5:2021.
Verifier dapat membuat permintaan OpenID4VP untuk SD-JWT dan mdoc saat menggunakan Credential Manager. Pilihannya bervariasi, bergantung pada kasus penggunaan dan pilihan industri.
Pendaftaran metadata kredensial
Pengelola Kredensial tidak menyimpan kredensial pemegang secara langsung, tetapi menyimpan metadata kredensial. Aplikasi pemegang harus mendaftarkan metadata kredensial terlebih dahulu
dengan Credential Manager menggunakan RegistryManager. Proses pendaftaran ini
membuat catatan registri yang memiliki dua tujuan utama:
- Pencocokan: Metadata kredensial terdaftar digunakan untuk mencocokkan dengan permintaan verifier mendatang.
- Tampilan: Elemen UI yang disesuaikan ditampilkan kepada pengguna di antarmuka pemilih kredensial.
Anda akan menggunakan class OpenId4VpRegistry untuk mendaftarkan kredensial digital Anda, karena class ini mendukung format kredensial mdoc dan SD-JWT. Verifikator akan mengirim
permintaan OpenID4VP untuk meminta kredensial ini.
Mendaftarkan kredensial aplikasi Anda
Untuk menggunakan Credential Manager Holder API, tambahkan dependensi berikut ke skrip build modul aplikasi Anda:
Groovy
dependencies { // Use to implement credentials registrys implementation "androidx.credentials.registry:registry-digitalcredentials-mdoc:1.0.0-alpha04" implementation "androidx.credentials.registry:registry-digitalcredentials-preview:1.0.0-alpha04" implementation "androidx.credentials.registry:registry-provider:1.0.0-alpha04" implementation "androidx.credentials.registry:registry-provider-play-services:1.0.0-alpha04" }
Kotlin
dependencies { // Use to implement credentials registrys implementation("androidx.credentials.registry:registry-digitalcredentials-mdoc:1.0.0-alpha04") implementation("androidx.credentials.registry:registry-digitalcredentials-preview:1.0.0-alpha04") implementation("androidx.credentials.registry:registry-provider:1.0.0-alpha04") implementation("androidx.credentials.registry:registry-provider-play-services:1.0.0-alpha04") }
Buat RegistryManager
Buat instance RegistryManager dan daftarkan permintaan OpenId4VpRegistry
dengannya.
// Create the registry manager
val registryManager = RegistryManager.create(context)
// The guide covers how to build this out later
val registryRequest = OpenId4VpRegistry(credentialEntries, id)
try {
registryManager.registerCredentials(registryRequest)
} catch (e: Exception) {
// Handle exceptions
}
Membangun permintaan OpenId4VpRegistry
Seperti yang disebutkan sebelumnya, Anda harus mendaftarkan OpenId4VpRegistry untuk menangani
permintaan OpenID4VP dari verifier. Kami akan mengasumsikan bahwa Anda telah memuat beberapa jenis data lokal dengan kredensial wallet Anda (misalnya, sdJwtsFromStorage). Sekarang Anda akan mengonversinya menjadi padanan DigitalCredentialEntry Jetpack kami berdasarkan formatnya - SdJwtEntry atau MdocEntry untuk SD-JWT atau mdoc.
Menambahkan Sd-JWT ke dalam registry
Petakan setiap kredensial SD-JWT lokal ke SdJwtEntry untuk registry:
fun mapToSdJwtEntries(sdJwtsFromStorage: List<StoredSdJwtEntry>): List<SdJwtEntry> {
val list = mutableListOf<SdJwtEntry>()
for (sdJwt in sdJwtsFromStorage) {
list.add(
SdJwtEntry(
verifiableCredentialType = sdJwt.getVCT(),
claims = sdJwt.getClaimsList(),
entryDisplayPropertySet = sdJwt.toDisplayProperties(),
id = sdJwt.getId() // Make sure this cannot be readily guessed
)
)
}
return list
}
Menambahkan mdocs ke Registry
Petakan kredensial mdoc lokal Anda ke jenis Jetpack MdocEntry:
fun mapToMdocEntries(mdocsFromStorage: List<StoredMdocEntry>): List<MdocEntry> {
val list = mutableListOf<MdocEntry>()
for (mdoc in mdocsFromStorage) {
list.add(
MdocEntry(
docType = mdoc.retrieveDocType(),
fields = mdoc.getFields(),
entryDisplayPropertySet = mdoc.toDisplayProperties(),
id = mdoc.getId() // Make sure this cannot be readily guessed
)
)
}
return list
}
Poin penting tentang kode
- Salah satu metode untuk mengonfigurasi kolom
idadalah dengan mendaftarkan ID kredensial terenkripsi, sehingga hanya Anda yang dapat mendekripsi nilai tersebut. - Kolom tampilan UI untuk kedua format harus dilokalkan.
Mendaftarkan kredensial Anda
Gabungkan entri yang dikonversi dan daftarkan permintaan dengan
RegistryManager:
val credentialEntries = mapToSdJwtEntries(sdJwtsFromStorage) + mapToMdocEntries(mdocsFromStorage)
val openidRegistryRequest = OpenId4VpRegistry(
credentialEntries = credentialEntries,
id = "my-wallet-openid-registry-v1" // A stable, unique ID to identify your registry record.
)
Sekarang, kita siap mendaftarkan kredensial Anda dengan CredentialManager.
try {
val response = registryManager.registerCredentials(openidRegistryRequest)
} catch (e: Exception) {
// Handle failure
}
Anda kini telah mendaftarkan kredensial Anda dengan Pengelola Kredensial.
Pengelolaan metadata aplikasi
Metadata yang didaftarkan aplikasi pemegang Anda dengan CredentialManager memiliki properti berikut:
- Persistensi: Informasi disimpan secara lokal dan tetap ada setelah perangkat di-reboot.
- Penyimpanan yang Terpisah: Setiap catatan registri aplikasi disimpan secara terpisah, yang berarti satu aplikasi tidak dapat mengubah catatan registri aplikasi lain.
- Pembaruan dengan Kunci: Setiap catatan registri aplikasi diberi kunci oleh
id, yang memungkinkan identifikasi ulang, pembaruan, atau penghapusan catatan. - Memperbarui Metadata: Sebaiknya perbarui metadata yang dipertahankan
setiap kali aplikasi Anda berubah atau dimuat pertama kali. Jika registri dipanggil beberapa
kali dalam
idyang sama, panggilan terakhir akan menggantikan semua catatan sebelumnya. Untuk memperbarui, daftar ulang tanpa perlu menghapus data lama terlebih dahulu.
Opsional: Buat pencocok
Pencocok adalah biner Wasm yang dijalankan Credential Manager di sandbox untuk memfilter kredensial terdaftar Anda terhadap permintaan Verifier yang masuk.
- Pencocok default: Class
OpenId4VpRegistrysecara otomatis menyertakan pencocokOpenId4VPdefault (OpenId4VpDefaults.DEFAULT_MATCHER) saat Anda membuat instance-nya. Untuk semua kasus penggunaan OpenID4VP standar, library menangani pencocokan untuk Anda. - Pencocok kustom: Anda hanya akan menerapkan pencocok kustom jika mendukung protokol non-standar yang memerlukan logika pencocokan sendiri.
Menangani kredensial yang dipilih
Saat pengguna memilih kredensial, aplikasi pemegang Anda perlu menangani permintaan tersebut.
Anda harus menentukan Aktivitas yang memproses filter intent androidx.credentials.registry.provider.action.GET_CREDENTIAL.
Dompet contoh kami menunjukkan prosedur ini.
Intent meluncurkan aktivitas Anda dengan permintaan Verifier dan asal panggilan,
yang Anda ekstrak dengan
fungsi PendingIntentHandler.retrieveProviderGetCredentialRequest. Metode ini menampilkan ProviderGetCredentialRequest yang berisi semua informasi yang terkait dengan permintaan verifikasi. Ada tiga komponen utama:
- Aplikasi pemanggil: Aplikasi yang membuat permintaan, dapat diambil dengan
getCallingAppInfo. - Kredensial yang dipilih: Informasi tentang kandidat yang dipilih pengguna, yang diambil melalui
selectedCredentialSet extension method; ini akan cocok dengan ID kredensial yang Anda daftarkan. - Permintaan spesifik: Permintaan spesifik yang dibuat oleh verifikator, diambil
dari metode
getCredentialOptions. Untuk alur permintaan Kredensial Digital, Anda dapat menemukan satuGetDigitalCredentialOptiondalam daftar ini.
Biasanya, pemverifikasi membuat permintaan presentasi kredensial digital, yang dapat Anda proses dengan contoh kode berikut:
request.credentialOptions.forEach { option ->
if (option is GetDigitalCredentialOption) {
Log.i(TAG, "Got DC request: ${option.requestJson}")
processRequest(option.requestJson)
}
}
Contohnya dapat dilihat di dompet contoh.
Periksa identitas verifikator
- Ekstrak
ProviderGetCredentialRequestdari intent:
val request = PendingIntentHandler.retrieveProviderGetCredentialRequest(intent)
- Periksa Origin dengan Hak Istimewa: Aplikasi dengan hak istimewa (seperti browser web) dapat melakukan panggilan atas nama verifier lain dengan menetapkan parameter origin. Untuk
mengambil asal ini, Anda harus meneruskan daftar pemanggil dengan hak istimewa dan tepercaya
(daftar yang diizinkan dalam format JSON) ke
getOrigin()APICallingAppInfo.
val origin = request?.callingAppInfo?.getOrigin(
privilegedAppsJson // Your allow list JSON
)
Jika origin tidak kosong: Origin akan ditampilkan jika packageName dan
sidik jari sertifikat yang didapatkan dari signingInfo cocok dengan aplikasi yang ditemukan
di daftar yang diizinkan yang diteruskan ke getOrigin() API. Setelah nilai asal diperoleh, aplikasi penyedia harus menganggapnya sebagai panggilan dengan hak istimewa dan menyetel asal ini pada respons OpenID4VP, bukan menghitung asal menggunakan tanda tangan aplikasi panggilan.
Pengelola Sandi Google menggunakan daftar yang diizinkan yang tersedia secara terbuka untuk panggilan ke
getOrigin(). Sebagai penyedia kredensial, Anda dapat menggunakan daftar ini atau memberikan daftar Anda sendiri dalam format JSON yang dijelaskan oleh API. Penyedia dapat memilih daftar mana yang akan digunakan. Untuk mendapatkan akses hak istimewa dengan penyedia kredensial pihak ketiga, lihat dokumentasi yang disediakan oleh pihak ketiga.
Jika origin kosong, permintaan verifikasi berasal dari aplikasi Android. Asal
aplikasi yang akan dimasukkan dalam respons OpenID4VP harus dihitung sebagai
android:apk-key-hash:<encoded SHA 256 fingerprint>.
val appSigningInfo = request?.callingAppInfo?.signingInfoCompat?.signingCertificateHistory[0]?.toByteArray()
val md = MessageDigest.getInstance("SHA-256")
val certHash = Base64.encodeToString(md.digest(appSigningInfo), Base64.NO_WRAP or Base64.NO_PADDING)
return "android:apk-key-hash:$certHash"
Merender UI Pemegang
Saat kredensial dipilih, aplikasi pemegang akan dipanggil, memandu pengguna melalui UI aplikasi. Ada dua cara standar untuk menangani alur kerja ini:
- Jika autentikasi pengguna tambahan diperlukan untuk merilis kredensial, gunakan BiometricPrompt API. Hal ini ditunjukkan dalam contoh.
- Jika tidak, banyak dompet memilih pengembalian senyap dengan merender aktivitas kosong yang segera meneruskan data kembali ke aplikasi yang memanggil. Hal ini meminimalkan klik pengguna dan memberikan pengalaman yang lebih lancar.
Menampilkan respons kredensial
Setelah aplikasi pemegang Anda siap mengirimkan hasilnya kembali, selesaikan aktivitas dengan respons kredensial:
PendingIntentHandler.setGetCredentialResponse(
resultData,
GetCredentialResponse(DigitalCredential(response.responseJson))
)
setResult(RESULT_OK, resultData)
finish()
Jika ada pengecualian, Anda dapat mengirim pengecualian kredensial dengan cara yang sama:
PendingIntentHandler.setGetCredentialException(
resultData,
GetCredentialUnknownException() // Configure the proper exception
)
setResult(RESULT_OK, resultData)
finish()
Lihat aplikasi contoh untuk contoh lengkap menampilkan respons kredensial dalam konteks.