Autentikasi Biometrik Mobile: Hal yang Harus Diverifikasi
Autentikasi biometrik adalah verifikasi pengguna secara lokal, bukan bukti identitas jarak jauh. Android dan Apple tidak memberi aplikasi akses ke template wajah atau sidik jari; aplikasi hanya menerima hasil berhasil atau gagal. Prompt hijau tidak boleh otomatis memberi izin untuk memakai sesi server lama, menyetujui transaksi berbeda, atau membuka rahasia tanpa kontrol lain.
Pertanyaan review lebih spesifik: operasi kriptografis apa yang terbuka setelah autentikasi lokal, berapa lama, dan melalui fallback apa? OWASP MASVS memisahkan risiko bypass autentikasi lokal, fallback lemah, tidak adanya step-up untuk tindakan sensitif, serta key yang tidak invalid setelah enrollment biometrik berubah.
Mulai dari operasi yang dilindungi
Buat satu baris untuk setiap operasi sebelum membaca kode. “Pakai Face ID” bukan requirement. “Menandatangani challenge server sebelum mengganti penerima transfer” adalah requirement.
| Operasi | Bukti lokal | Kontrol server | Owner bukti | Kriteria lulus |
|---|---|---|---|---|
| Membuka data akun cache | credential perangkat dapat diterima | sesi tetap valid | owner mobile | data tidak dapat didekripsi sebelum prompt sukses |
| Menyetujui pembayaran | biometrik kuat dan prompt baru | server memeriksa challenge, nominal, penerima, masa berlaku | owner pembayaran | nominal berubah membatalkan persetujuan |
| Mengekspor materi recovery | tanpa shortcut lokal | autentikasi ulang dan keputusan kebijakan | owner identitas | fallback tidak melemahkan kebijakan |
Challenge harus memuat tindakan, akun, ID transaksi, masa berlaku, dan nonce. Jangan menandatangani string generik seperti “approved”. Server wajib menolak bukti yang diputar ulang, kedaluwarsa, atau untuk tindakan lain.
Ikat prompt ke penggunaan key
Prompt visual saja lemah: aplikasi dapat menampilkan prompt lalu memakai key atau token yang sudah tersedia. Ikat autentikasi ke operasi private key atau item Keychain yang dilindungi. Android dapat menerima CryptoObject pada BiometricPrompt; buat key Keystore yang mewajibkan autentikasi pengguna, lalu gunakan cipher atau signature yang diinisialisasi hanya setelah prompt sukses.
val spec = KeyGenParameterSpec.Builder(alias, PURPOSE_SIGN)
.setUserAuthenticationRequired(true)
.setUserAuthenticationParameters(0, AUTH_BIOMETRIC_STRONG)
.setInvalidatedByBiometricEnrollment(true)
.build()
// authenticate(promptInfo, BiometricPrompt.CryptoObject(signature))
Nilai 0 pada contoh berarti autentikasi untuk setiap penggunaan. Verifikasi kombinasi API, hardware, dan authenticator yang benar-benar didukung; jangan menyalin konfigurasi menjadi kebijakan produksi tanpa pengujian perangkat. Di iOS, LAContext mengevaluasi kebijakan, sementara kontrol akses Keychain dapat meminta biometri saat ini untuk item yang dilindungi. Rahasia atau private key harus tetap berada di penyimpanan platform, bukan diganti flag biometrik buatan aplikasi.
Dokumentasi Apple menyatakan LocalAuthentication hanya memberi hasil Boolean dan tidak memberi data sidik jari atau wajah. Pemilihan authenticator Android juga menentukan risiko: BIOMETRIC_STRONG dan credential perangkat bukan kebijakan yang sama. Catat pilihan dan alasannya untuk tiap operasi.
Fallback adalah kebijakan
Fallback terjadi bila biometri tidak tersedia, belum didaftarkan, terkunci, dibatalkan, atau sengaja dimatikan. PIN/passcode perangkat mungkin dapat diterima untuk membuka data lokal berisiko rendah, tetapi mengubah assurance. PIN dukungan di UI aplikasi, password yang diingat, atau “lanjutkan saja” bukan fallback setara.
| Kejadian | Perilaku wajib | Sinyal gagal | Perbaikan |
|---|---|---|---|
| sukses biometrik | lakukan operasi terikat sekali | operasi sukses tanpa objek terikat | buat ulang key dan uji |
| pengguna membatalkan | berhenti tanpa perubahan state | request tetap berjalan | pisahkan callback cancel dan sukses |
| lockout/tidak tersedia | recovery yang disetujui atau berhenti | downgrade diam-diam | minta autentikasi server eksplisit |
| fallback credential | hanya bila owner risiko menyetujui | tindakan sensitif menerimanya | hapus fallback dari tindakan itu |
| enrollment berubah | invalidasi atau bentuk ulang material | key lama masih bekerja | rotasi key dan wajib sign-in |
Jangan perlakukan kegagalan biometrik sebagai keputusan otorisasi. Biometrik lokal dapat membuka key; server tetap memeriksa sesi, hak akun, batas tindakan, dan freshness transaksi.
Bukti uji dan gate rilis
Owner keamanan mobile mencatat model perangkat, versi OS, kebijakan authenticator, dan hasil. Owner fitur mencatat keputusan fallback. Owner backend mencatat validasi challenge. Bukti mencakup cuplikan kode, ID build bertanda tangan, rekaman alur prompt, dan trace yang membuktikan tidak ada signature atau dekripsi setelah cancel, lockout, perubahan enrollment, atau challenge kedaluwarsa.
Lulus bila setiap tindakan sensitif memakai authenticator yang sengaja dipilih, binding kriptografis saat key penting, fallback terdefinisi, dan proteksi replay di server. Gagal bila Boolean sukses saja mengizinkan tindakan, fallback tidak terdokumentasi, data tetap terbaca setelah sesi berakhir, atau enrollment baru tidak memengaruhi key lama. Pengecualian aksesibilitas atau dukungan perangkat hanya berlaku bila owner risiko mendokumentasikan cakupan, kontrol kompensasi server, masa berlaku, dan tanggal review. Perbaiki dengan mempersempit tindakan, meminta autentikasi server baru, merotasi key, lalu ulangi uji jalur gagal.
Pengujian aplikasi mobile dapat memeriksa build dan perilaku perangkat; pengujian tidak menggantikan persetujuan risiko transaksi.
Kasus kerja: perubahan penerima
Penguji memulai sesi terautentikasi, membuka layar perubahan penerima, lalu memanggil prompt biometrik. Rekam byte request sebelum konfirmasi. Output yang diharapkan adalah challenge server sekali pakai; payload bertanda tangan menyebut ID penerima, rekening tujuan, operasi, masa berlaku, dan nonce. Ubah satu digit rekening setelah prompt tampil lalu kirim bukti lama. Server harus menolak karena konteks bertanda tangan tidak lagi sama dengan perubahan yang diminta. Ulangi setelah pembatalan, lockout biometrik, dan perubahan enrollment. Bukti penutupan berupa trace perangkat serta catatan penolakan server untuk tiap jalur, hanya memakai ID run pengujian. Uji ini membedakan tampilan prompt dari otorisasi kriptografis.
Uji tepi sebelum penutupan
Coba pakai ulang signature valid, pulihkan aplikasi dari background, dan kirim setelah challenge kedaluwarsa. Pastikan tidak ada mutasi tertunda sesudah tiap request ditolak. Uji jalur credential perangkat yang didukung secara terpisah; laporkan keputusan kebijakannya, bukan menyebutnya setara biometrik. Uji ulang build rilis, catat versi aplikasi dan versi validasi backend, lalu tutup hanya jika output gagal tidak mengubah state dan output sukses mengubah penerima yang diminta saja.