Розробка авторизації за біометрією (відбиток пальця) в Android-додатку

TRUETECH займається розробкою, підтримкою та обслуговуванням мобільних додатків iOS, Android, PWA. Маємо великий досвід та експертизу для публікації мобільних додатків до популярних маркетів Google Play, App Store, Amazon, AppGallery та інші.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1735 послуг
Розробка авторизації за біометрією (відбиток пальця) в Android-додатку
Простий
~1 день
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    495

Розробка авторизації по біометрії (відбиток пальця) у Android-приложенні

На Android біометрія пройшла довгий шлях: FingerprintManager (deprecated API 28), BiometricPrompt (з'явився в API 28, нормально працював у 29–30), і нарешті стабільна бібліотека androidx.biometric:biometric версії 1.2+. Якщо приложення досі використовує FingerprintManager — це технічний долг, який вистрелить при таргеті API 34.

Що ломається частіше за все

BiometricPrompt вимагає передачі FragmentActivity або Fragment. Розробники іноді намагаються вико вити його з ViewModel або Repository — отримують IllegalStateException в рантаймі. Prompt живе в UI-шарі, точка.

Другий камінь — CryptoObject. Багато реалізацій викликають BiometricPrompt.authenticate() без CryptoObject, тобто перевіряють тільки присутність біометрії, але не прив'язують її до крипто-операції. Це "слабка" біометрія: зловмисник з root-доступом теоретично може підробити результат аутентифікації, інжектуючи SUCCESS у AuthenticationCallback. Правильний шлях — Class 3 (Strong) біометрія з CryptoObject.

Третій — фрагментація Android. На MIUI 12–13 BiometricManager.canAuthenticate(BIOMETRIC_STRONG) повертає BIOMETRIC_ERROR_NONE_ENROLLED навіть при зареєстрованих відбитках через кастомізацію Xiaomi. Потрібно добавити fallback-перевірку через FingerprintManagerCompat для таких випадків.

Правильна реалізація з CryptoObject

Суть: генеруємо ключ в Android Keystore, прив'язаний до біометрії. При аутентифікації Cipher ініціалізується цим ключем і передається у CryptoObject. Якщо біометрія пройшла успішно — cipher розблокований та можна шифрувати/розшифровувати дані.

val keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
keyGenerator.init(
    KeyGenParameterSpec.Builder(KEY_NAME, KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
        .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
        .setUserAuthenticationRequired(true)
        .setInvalidatedByBiometricEnrollment(true)
        .build()
)
keyGenerator.generateKey()

setInvalidatedByBiometricEnrollment(true) — ключ інвалідується при додаванні нового відбитку. Без цього флага старий ключ залишається робочим після зміни біометрії користувачем.

Після генерації ключа:

val cipher = Cipher.getInstance("${KeyProperties.KEY_ALGORITHM_AES}/${KeyProperties.BLOCK_MODE_CBC}/${KeyProperties.ENCRYPTION_PADDING_PKCS7}")
val keyStore = KeyStore.getInstance("AndroidKeyStore").apply { load(null) }
val secretKey = keyStore.getKey(KEY_NAME, null) as SecretKey
cipher.init(Cipher.ENCRYPT_MODE, secretKey)

val cryptoObject = BiometricPrompt.CryptoObject(cipher)

Потім передаємо cryptoObject у biometricPrompt.authenticate(promptInfo, cryptoObject).

Callback обов'язково обробляємо повністю

object : BiometricPrompt.AuthenticationCallback() {
    override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
        val cipher = result.cryptoObject?.cipher ?: return
        // розшифровуємо токен з EncryptedSharedPreferences
    }
    override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
        when (errorCode) {
            BiometricPrompt.ERROR_LOCKOUT -> showFallback()
            BiometricPrompt.ERROR_LOCKOUT_PERMANENT -> showPermanentLockout()
            BiometricPrompt.ERROR_NEGATIVE_BUTTON -> showPinAuth()
            BiometricPrompt.ERROR_USER_CANCELED -> { /* нічого не робимо */ }
        }
    }
    override fun onAuthenticationFailed() {
        // спроба не вдалася, але ліміт не вичерпаний — BiometricPrompt сам показує помилку
    }
}

onAuthenticationFailed — не фінальна помилка. Система сама оновлює UI промпта. Не приховуйте промпт та не показуйте свої помилки в цьому callback.

Зберігання токена

Використовуємо EncryptedSharedPreferences з androidx.security:security-crypto. Шифруємо token через cipher з успішного CryptoObject, зберігаємо зашифровані байти + IV в EncryptedSharedPreferences. При наступній авторизації: розворачуємо біометрію в режимі DECRYPT_MODE із збереженим IV → отримуємо plaintext токен.

Етапи та терміни

Перевірка мінімального API рівня (наш таргет — API 23+, BiometricPrompt працює з API 28 через androidx.biometric) → реалізація KeyStore-ключа та CryptoObject-flow → UI промпта з кастомними текстами → обробка всіх error codes → тестування на реальних пристроях (Samsung Galaxy, Xiaomi, Pixel) → покриття unit-тестами через mock BiometricPrompt.

Терміни — 3–6 робочих днів. На Xiaomi та пристроях з кастомними прошивками добавляємо час на окремої перевірки сумісності.