Sebelum pengguna Anda dapat melakukan autentikasi dengan kunci sandi, aplikasi Anda harus mendaftarkan atau membuat kunci sandi untuk akun mereka terlebih dahulu.
Untuk membuat kunci sandi, dapatkan detail yang diperlukan untuk membuat kunci sandi dari server aplikasi Anda, lalu panggil Credential Manager API, yang akan menampilkan pasangan kunci publik dan pribadi. Kunci pribadi yang ditampilkan disimpan di penyedia kredensial, seperti Pengelola Sandi Google, sebagai kunci sandi. Kunci publik disimpan di server aplikasi Anda.
Prasyarat
Pastikan Anda telah menyiapkan Digital Asset Links dan menargetkan perangkat yang menjalankan Android 9 (API level 28) atau yang lebih tinggi.
Ringkasan
Panduan ini berfokus pada perubahan yang diperlukan di aplikasi klien pihak tepercaya untuk membuat kunci sandi, dan memberikan ringkasan singkat tentang penerapan server aplikasi pihak tepercaya. Untuk mempelajari lebih lanjut integrasi sisi server, lihat Pendaftaran kunci sandi sisi server.
- Tambahkan dependensi ke aplikasi Anda: Tambahkan library Credential Manager yang diperlukan.
- Buat instance Credential Manager: Buat instance Credential Manager.
- Dapatkan opsi pembuatan kredensial dari server aplikasi: Dari server aplikasi Anda, kirimkan detail yang diperlukan untuk membuat kunci sandi ke aplikasi klien, seperti informasi tentang aplikasi, pengguna, serta
challengedan kolom lainnya. - Meminta kunci sandi: Di aplikasi Anda, gunakan detail yang diterima dari server aplikasi untuk membuat objek
GetPublicKeyCredentialOptiondan gunakan objek ini untuk memanggil metodecredentialManager.getCredential()guna membuat kunci sandi. - Tangani respons pembuatan kunci sandi: Saat menerima kredensial di aplikasi klien, Anda harus mengenkode, melakukan serialisasi, lalu mengirim kunci publik ke server aplikasi. Anda juga harus menangani setiap pengecualian yang dapat terjadi dalam kasus pembuatan kunci sandi.
- Verifikasi dan simpan kunci publik di server: Selesaikan langkah-langkah sisi server untuk memverifikasi asal kredensial, lalu simpan kunci publik.
- Memberi tahu pengguna: Memberi tahu pengguna bahwa kunci sandinya telah dibuat.
1. Menambahkan dependensi ke aplikasi
Tambahkan dependensi berikut ke file build.gradle modul aplikasi Anda:
Kotlin
dependencies { implementation("androidx.credentials:credentials:1.6.0-beta03") implementation("androidx.credentials:credentials-play-services-auth:1.6.0-beta03") }
Groovy
dependencies { implementation "androidx.credentials:credentials:1.6.0-beta03" implementation "androidx.credentials:credentials-play-services-auth:1.6.0-beta03" }
2. Buat instance Credential Manager
Gunakan konteks aplikasi atau aktivitas Anda untuk membuat objek CredentialManager.
// Use your app or activity context to instantiate a client instance of
// CredentialManager.
private val credentialManager = CredentialManager.create(context)
3. Mendapatkan opsi pembuatan kredensial dari server aplikasi Anda
Saat pengguna mengklik tombol "Buat Kunci Sandi" atau saat pengguna baru mendaftar, buat permintaan dari aplikasi Anda ke server aplikasi Anda untuk mendapatkan informasi yang diperlukan untuk memulai proses pendaftaran kunci sandi.
Gunakan library yang kompatibel dengan FIDO di server aplikasi Anda untuk mengirimkan informasi yang diperlukan guna membuat kunci sandi ke aplikasi klien Anda, seperti informasi tentang pengguna, aplikasi, dan properti konfigurasi tambahan. Untuk mempelajari lebih lanjut, lihat Pendaftaran kunci sandi sisi server.
Di aplikasi klien, dekode opsi pembuatan kunci publik yang dikirim oleh server aplikasi. Data ini biasanya ditampilkan dalam format JSON. Untuk mempelajari lebih lanjut cara dekode ini dilakukan untuk klien web, lihat Encoding dan Decoding. Untuk aplikasi klien Android, Anda harus menangani decoding secara terpisah.
Cuplikan berikut menunjukkan struktur opsi pembuatan kunci publik yang dikirim oleh server aplikasi:
{
"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"
}
}
Kolom utama dalam opsi pembuatan kunci publik mencakup:
challenge: String acak yang dibuat server dan digunakan untuk mencegah serangan replay.rp: Detail tentang aplikasi.rp.name: Nama aplikasi.rp.id: Domain atau subdomain aplikasi.
user: Detail tentang pengguna.id: ID unik pengguna. Nilai ini tidak boleh menyertakan informasi identitas pribadi, misalnya, alamat email atau nama pengguna. Anda dapat menggunakan nilai acak 16 byte.name: ID unik untuk akun yang akan dikenali pengguna, seperti alamat email atau nama penggunanya. ID unik ini akan ditampilkan di pemilih akun. Jika menggunakan nama pengguna, gunakan nilai yang sama seperti pada autentikasi sandi.displayName: Nama opsional yang mudah digunakan untuk akun yang dimaksudkan untuk ditampilkan di pemilih akun.
authenticatorSelection: Detail tentang perangkat yang akan digunakan untuk autentikasi.authenticatorAttachment: Menunjukkan autentikator pilihan. Kemungkinan nilainya adalah sebagai berikut: -platform: Nilai ini digunakan untuk pengautentikasi yang terpasang di perangkat pengguna, seperti sensor sidik jari. -cross-platform: Nilai ini digunakan untuk perangkat roaming seperti kunci keamanan. Biasanya tidak digunakan dalam konteks kunci sandi. - Tidak ditentukan (direkomendasikan): Jika nilai ini tidak ditentukan, pengguna dapat membuat kunci sandi di perangkat pilihan mereka. Dalam sebagian besar kasus, tidak menentukan parameter adalah opsi terbaik.requireResidentKey: Untuk membuat kunci sandi, tetapkan nilai kolomBooleanini ketrue.residentKey: Untuk membuat kunci sandi, tetapkan nilai kerequired.userVerification: Digunakan untuk menentukan persyaratan verifikasi pengguna selama pendaftaran kunci sandi. Nilai yang mungkin adalah sebagai berikut: -preferred: Gunakan nilai ini jika Anda memprioritaskan pengalaman pengguna daripada perlindungan, seperti di lingkungan tempat verifikasi pengguna menyebabkan lebih banyak hambatan daripada perlindungan. -required: Gunakan nilai ini jika pemanggilan metode verifikasi pengguna yang tersedia di perangkat diperlukan. -discouraged: Gunakan nilai ini jika penggunaan metode verifikasi pengguna tidak disarankan.
Untuk mempelajari lebih lanjutuserVerification, lihat pembahasan mendalam userVerification.
excludeCredentials: Mencantumkan ID kredensial dalam array untuk mencegah pembuatan kunci sandi duplikat jika sudah ada yang memiliki penyedia kredensial yang sama.
4. Meminta kunci sandi
Setelah Anda mengurai opsi pembuatan kunci publik sisi server, buat
kunci sandi dengan membungkus opsi ini dalam objek CreatePublicKeyCredentialRequest
dan memanggil createCredential().
createPublicKeyCredentialRequest mencakup hal berikut:
requestJson: Opsi pembuatan kredensial yang dikirim oleh server aplikasi.preferImmediatelyAvailableCredentials: Ini adalah kolom Boolean opsional yang menentukan apakah hanya menggunakan kredensial yang tersedia secara lokal atau kredensial yang disinkronkan penyedia kredensial untuk memenuhi permintaan, bukan kredensial dari kunci keamanan atau alur kunci campuran. Kemungkinan penggunaannya adalah sebagai berikut:false(default): Gunakan nilai ini jika panggilan ke Pengelola Kredensial dipicu oleh tindakan pengguna yang eksplisit.true: Gunakan nilai ini jika Credential Manager dipanggil secara oportunistik, seperti saat pertama kali membuka aplikasi.
Jika Anda menyetel nilai ketruedan tidak ada kredensial yang langsung tersedia, Credential Manager tidak akan menampilkan UI apa pun dan permintaan akan segera gagal, sehingga menampilkan NoCredentialException untuk permintaan get danCreateCredentialNoCreateOptionExceptionuntuk permintaan create.
origin: Kolom ini otomatis ditetapkan untuk aplikasi Android. Untuk browser dan aplikasi dengan hak istimewa serupa yang perlu menetapkanorigin, lihat Melakukan panggilan Credential Manager atas nama pihak lain untuk aplikasi dengan hak istimewa.isConditional: Ini adalah kolom opsional yang secara default ditetapkan kefalse. Jika Anda menyetelnya ketruedan pengguna tidak memiliki kunci sandi, Anda akan otomatis membuat kunci sandi untuknya saat dia login berikutnya dengan sandi tersimpan. Kunci sandi disimpan di penyedia kredensial pengguna. Fitur pembuatan bersyarat memerlukan versi terbaruandroidx.credentials.
Memanggil fungsi createCredential() akan meluncurkan UI sheet bawah bawaan Credential Manager yang meminta pengguna untuk menggunakan kunci sandi dan memilih penyedia kredensial dan akun untuk penyimpanan. Namun, jika isConditional disetel
ke true, UI sheet bawah tidak ditampilkan, dan kunci sandi
dibuat secara otomatis.
5. Menangani respons
Setelah pengguna diverifikasi menggunakan kunci layar perangkat, kunci sandi akan dibuat dan disimpan di penyedia kredensial pilihan pengguna.
Respons setelah Anda berhasil memanggil createCredential() adalah objek
PublicKeyCredential.
PublicKeyCredential akan terlihat seperti berikut:
{
"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"
}
Di aplikasi klien, serialisasikan objek dan kirimkan ke server aplikasi.
Tambahkan kode untuk menangani kegagalan seperti yang ditunjukkan dalam cuplikan berikut:
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}")
}
}
6. Verifikasi dan simpan kunci publik di server aplikasi
Di server aplikasi, Anda harus memverifikasi kredensial kunci publik, lalu menyimpan kunci publik.
Untuk memverifikasi origin kredensial kunci publik, bandingkan dengan daftar yang diizinkan dari aplikasi yang disetujui. Jika kunci memiliki origin yang tidak dikenal, tolak kunci tersebut.
Untuk mendapatkan sidik jari SHA 256 aplikasi:
Cetak sertifikat penandatanganan aplikasi rilis Anda dengan menjalankan perintah berikut di terminal:
keytool -list -keystore <path-to-apk-signing-keystore>Dalam respons, identifikasi sidik jari SHA 256 sertifikat penandatanganan, yang disebutkan sebagai
Certificate fingerprints block:SHA256.Enkode sidik jari SHA256 dengan encoding base64url. Contoh Python ini menunjukkan cara mengenkode sidik jari dengan benar:
import binascii import base64 fingerprint = '<SHA256 finerprint>' # your app's SHA256 fingerprint print(base64.urlsafe_b64encode(binascii.a2b_hex(fingerprint.replace(':', ''))).decode('utf8').replace('=', ''))Tambahkan
android:apk-key-hash: di awal output dari langkah sebelumnya sehingga Anda mendapatkan sesuatu yang mirip dengan berikut ini:android:apk-key-hash:<encoded SHA 256 fingerprint>Hasilnya harus cocok dengan asal yang diizinkan di server aplikasi Anda. Jika Anda memiliki beberapa sertifikat penandatanganan, seperti sertifikat untuk proses debug dan rilis, atau beberapa aplikasi, ulangi proses dan setujui semua origin sebagai valid di server aplikasi.
7. Memberi tahu pengguna
Setelah kunci sandi berhasil dibuat, beri tahu pengguna Anda tentang kunci sandi tersebut dan beri tahu mereka bahwa mereka dapat mengelola kunci sandi dari aplikasi penyedia kredensial mereka atau dari dalam setelan aplikasi. Memberi tahu pengguna dengan menggunakan dialog, notifikasi, atau snackbar kustom. Karena pembuatan kunci sandi yang tidak terduga oleh entitas berbahaya memerlukan pemberitahuan keamanan segera, pertimbangkan untuk melengkapi metode dalam aplikasi ini dengan komunikasi eksternal, seperti email.
Meningkatkan pengalaman pengguna
Untuk meningkatkan pengalaman pengguna saat menerapkan pendaftaran dengan Pengelola Kredensial, pertimbangkan untuk menambahkan fungsi guna memulihkan kredensial dan menekan dialog isi otomatis.
Menambahkan fungsi untuk memulihkan kredensial di perangkat baru
Untuk mengizinkan pengguna login ke akun mereka dengan lancar di perangkat baru, terapkan fungsi Pulihkan Kredensial. Menambahkan kredensial pemulihan dengan
BackupAgent membuat pengguna login saat mereka membuka aplikasi yang dipulihkan di perangkat baru,
sehingga mereka dapat langsung menggunakan aplikasi Anda.
Menonaktifkan isi otomatis pada kolom kredensial (opsional)
Untuk layar aplikasi tempat pengguna diharapkan menggunakan UI sheet bawah Pengelola Kredensial untuk autentikasi, tambahkan atribut isCredential ke kolom nama pengguna dan sandi. Hal ini mencegah dialog isi otomatis (FillDialog dan
SaveDialog) tumpang-tindih dengan UI sheet bawah Credential Manager.
Atribut isCredential didukung di Android 14 dan yang lebih tinggi.
Contoh berikut menunjukkan cara menambahkan atribut isCredential
ke kolom nama pengguna dan sandi yang relevan dalam tampilan yang relevan untuk aplikasi Anda:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:isCredential="true" />