BiometricPrompt.authenticate с CryptoObject не работаетAndroid

Форум для тех, кто программирует под Android
Anonymous
BiometricPrompt.authenticate с CryptoObject не работает

Сообщение Anonymous »

Я пытаюсь реализовать биометрическую аутентификацию с помощью экземпляра CryptoObject, как показано в подобных сообщениях https://medium.com/androiddevelopers/us ... ce500ccdb7.
К сожалению, я не могу заставить его работать. Вместо этого я получаю следующее исключение:

Код: Выделить всё

android.security.keystore.UserNotAuthenticatedException: User not authenticated
Похоже, это вызвано вызовом cipher.init() перед аутентификацией. Однако отсутствие вызова cipher.init() до аутентификации приводит к другому исключению:

Код: Выделить всё

java.lang.IllegalStateException: Crypto primitive not initialized
Значит, должен быть определенный порядок, который я не понимаю.
Сейчас я использую androidx.biometric:biometric:1.1.0, поскольку это последняя стабильная версия, как показано здесь: https://developer.android.com/jetpack/a ... /biometric
Сначала я создаю экземпляр Cipher:

Код: Выделить всё

    private val ENCRYPTION_BLOCK_MODE = KeyProperties.BLOCK_MODE_CBC
private val ENCRYPTION_PADDING = KeyProperties.ENCRYPTION_PADDING_PKCS7
private val ENCRYPTION_ALGORITHM = KeyProperties.KEY_ALGORITHM_AES

override fun getInitializedCypherForEncryption(): Cipher {
val cipher = getCipher()
val secretKey = getOrCreateSecretKey(KEY_NAME)
cipher.init(Cipher.ENCRYPT_MODE, secretKey)
return cipher
}

private fun getCipher(): Cipher {
val transformation = "$ENCRYPTION_ALGORITHM/$ENCRYPTION_BLOCK_MODE/$ENCRYPTION_PADDING"
return Cipher.getInstance(transformation)
}

private fun getOrCreateSecretKey(keyName: String): SecretKey {
val keyStore = KeyStore.getInstance("AndroidKeyStore").apply {
load(null)
}
keyStore.getKey(keyName, null)?.let {
return it as SecretKey
}

val paramsBuilder = KeyGenParameterSpec.Builder(
keyName,
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
).apply {
setBlockModes(ENCRYPTION_BLOCK_MODE)
setEncryptionPaddings(ENCRYPTION_PADDING)
setKeySize(KEY_SIZE)
setUserAuthenticationRequired(true)
setInvalidatedByBiometricEnrollment(true)

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
setUserAuthenticationParameters(
5,
KeyProperties.AUTH_BIOMETRIC_STRONG
)
} else {
setUserAuthenticationValidityDurationSeconds(5)
}

}

val keyGenParams = paramsBuilder.build()
val keyGenerator = KeyGenerator.getInstance(
ENCRYPTION_ALGORITHM,
"AndroidKeyStore"
)
keyGenerator.init(keyGenParams)
return keyGenerator.generateKey()
}
Затем я создаю CryptoObject:

Код: Выделить всё

val cryptoObject = BiometricPrompt.CryptoObject(cipher)
После этого я определяю BiometricPrompt и запускаю аутентификацию:

Код: Выделить всё

        val biometricPrompt = BiometricPrompt(activity, callback)
val promptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle("Unlock device")
.setNegativeButtonText("Cancel")
.setAllowedAuthenticators(BIOMETRIC_STRONG)
.build()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
biometricPrompt.authenticate(promptInfo, cryptoObject)
} else {
biometricPrompt.authenticate(promptInfo)
}
Итак, весь код выглядит так:

Код: Выделить всё

    fun test(activity: FragmentActivity) {
val cipher = cryptographyManager.getInitializedCypherForEncryption()
val cryptoObject = BiometricPrompt.CryptoObject(cipher)
val callback = object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
super.onAuthenticationSucceeded(result)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
result.cryptoObject?.cipher?.let {
// Do something
}
} else {
// Do something
}
}
}

val biometricPrompt = BiometricPrompt(activity, callback)
val promptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle("Unlock device")
.setNegativeButtonText("Cancel")
.setAllowedAuthenticators(BIOMETRIC_STRONG)
.build()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
biometricPrompt.authenticate(promptInfo, cryptoObject)
} else {
biometricPrompt.authenticate(promptInfo)
}
}
Затем в первой строке кода создается исключение.

Подробнее здесь: https://stackoverflow.com/questions/797 ... ot-working

Вернуться в «Android»