I am using the new androidx.BiometricPromt
library to implement authentication with a fingerprint. I want to invalidate key if the user added new fingerprint or deleted one. I am creating key like this:
fun getSecretKey(shouldCreate: Boolean): Key {
val keyStore = KeyStore.getInstance(ANDROID_KEYSTORE)
keyStore.load(null)
return if (shouldCreate) {
createSecretKey(keyStore)
} else {
keyStore.getKey(ALIAS_BIOMETRICS, null)
}
}
private fun createSecretKey(keystore: KeyStore): Key {
val builder = KeyGenParameterSpec.Builder(
ALIAS_BIOMETRICS,
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
.setUserAuthenticationRequired(true)
.setUserAuthenticationValidityDurationSeconds(5)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
builder.setInvalidatedByBiometricEnrollment(true)
builder.setUserAuthenticationValidWhileOnBody(true)
}
val keyGenerator =
KeyGenerator.getInstance(keyAlgorithm, keystore.provider)
keyGenerator
.init(builder.build())
return keyGenerator.generateKey()
}
And I am starting biometric scan process like this:
val info = BiometricPrompt.PromptInfo.Builder()
.setTitle(context.getString(R.string.biometric_dialog_title))
.setSubtitle(context.getString(R.string.biometric_dialog_subtitle))
.setNegativeButtonText(context.getString(R.string.biometric_dialog_cancel))
.build()
biometricPrompt = when (screen) {
is FragmentActivity -> BiometricPrompt(screen, { it.run() }, this)
is Fragment -> BiometricPrompt(screen, { it.run() }, this)
else -> throw IllegalArgumentException("Screen type must be FragmentActivity or Fragment")
}
biometricPrompt?.authenticate(info)
I wanted to start biometricPromt?.authenticate(info, cryptoObject)
but in this case I need to initialize Cipher and it throwing the exception UserNotAuthenticated
. After user successfully scanned biometrics I am creating the SecretKey and use for encryption. Then I am changing fingerprints (add some new fingerprints and remove). And decryption process like encryption but only when getting key I am not creating new one but getting it from keystore. Although I am changed fingerprints everything decyrpting fine.
I want to deny decrypting if user changed fingerprints in his device. How to achieve this functionality with androidx.BiometricPrompt library?