Sparround

Biometric authentication

BiometricPrompt (androidx.biometric) — barmaq izi/üz tanıma üçün vahid API: sistem dialoqunu göstərir, sensor fərqlərini gizlədir.

Açar anlayışlar:

  • Authenticator sinifləri: BIOMETRIC_STRONG (Class 3 — kriptoqrafik əməliyyatlara icazəli), BIOMETRIC_WEAK (Class 2), DEVICE_CREDENTIAL (PIN/pattern fallback).
  • canAuthenticate() — cihazda biometrika var/qurulub/əlçatandır yoxlaması; nəticəyə görə enrollment-ə yönləndirmə.
  • CryptoObject — biometrikanın kriptoqrafiya ilə bağlanması: Keystore açarı setUserAuthenticationRequired(true) ilə yaradılır, cipher yalnız uğurlu biometrikadan sonra işləyir.

Kritik fərq — iki səviyyə:

  • Zəif inteqrasiya: onAuthenticationSucceeded → sadəcə if (success) unlock() — Frida ilə hook-lanıb keçilə bilər.
  • Güclü inteqrasiya: uğur callback-i CryptoObject-dəki cipher-i verir → onunla real data (refresh token) decrypt olunur — biometrikasız data açılmır, hook faydasızdır.

Bank tətbiqində: giriş üçün biometrika + kritik əməliyyatlar (böyük köçürmə, limit dəyişikliyi) üçün təkrar təsdiq (step-up auth).

kotlin
// Keystore açarı: yalnız auth-dan sonra istifadə oluna bilər
private fun buildKey() {
    val spec = KeyGenParameterSpec.Builder(
        "biometric_key",
        KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
    )
        .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
        .setUserAuthenticationRequired(true)               // biometrika şərti
        .setInvalidatedByBiometricEnrollment(true)          // yeni barmaq → açar ləğv
        .build()
    KeyGenerator.getInstance("AES", "AndroidKeyStore")
        .apply { init(spec) }.generateKey()
}

val prompt = BiometricPrompt(this, executor,
    object : BiometricPrompt.AuthenticationCallback() {
        override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
            val cipher = result.cryptoObject?.cipher ?: return
            val token = String(cipher.doFinal(encryptedRefreshToken))  // real decrypt
            proceedWithLogin(token)
        }
    })

prompt.authenticate(
    BiometricPrompt.PromptInfo.Builder()
        .setTitle("Bank hesabınıza giriş")
        .setAllowedAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG)
        .setNegativeButtonText("PIN ilə daxil ol")
        .build(),
    BiometricPrompt.CryptoObject(cipher)
)

CryptoObject ilə güclü inteqrasiya

Müsahibə sualı: "Yeni barmaq izi əlavə olunanda nə baş verməlidir?" Bank cavabı: setInvalidatedByBiometricEnrollment(true) ilə açar avtomatik ləğv olunur → istifadəçi tam credential-larla yenidən daxil olur → biometrika yenidən aktivləşdirilir. Səbəb: hücumçu cihaza öz barmağını əlavə edib girə bilməsin. UX-təhlükəsizlik balansıdır — kritik olmayan tətbiqlər bunu etmir, bank etməlidir.

🛠 Tapşırıq

BiometricPrompt ilə iki səviyyəni müqayisə et:

  • Əvvəl sadə variant: onAuthenticationSucceededunlock(). Emulyatorda barmaq izi qeydiyyatı ilə test et.
  • Sonra güclü variant: Keystore-da setUserAuthenticationRequired(true) açarı yarat, bir mətni onunla şifrələ və yalnız CryptoObject ilə açılmasını təmin et.
  • Emulyatorda yeni barmaq izi əlavə et və setInvalidatedByBiometricEnrollment səbəbindən açarın ləğv olduğunu gör.

Bitdi sayılır: iki yanaşmanın hücumçu üçün fərqini bir cümlə ilə deyirsənsə.

📚 Mənbələr və sənədlər