Разработка авторизации по биометрии (отпечаток пальца) в 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 и устройствах с кастомными прошивками добавляем время на отдельную проверку совместимости.