К сожалению, я не могу заставить его работать. Вместо этого я получаю следующее исключение:
Код: Выделить всё
android.security.keystore.UserNotAuthenticatedException: User not authenticatedКод: Выделить всё
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()
}
Код: Выделить всё
val cryptoObject = BiometricPrompt.CryptoObject(cipher)Код: Выделить всё
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