I am attempting to perform a signing operation with a secret key that can only be used after user authenticates with their device biometrics. I have the logic like this
val mac = initMac(keyAlias)
val biometricPrompt = createBiometricPrompt()
biometricPrompt.authenticate(promptInfo, BiometricPrompt.CryptoObject(mac))
The initMac
function gets a Mac Crypto object to be used for the signing after successful authentication
private fun initMac(keyName: String): Mac {
val keyStore = KeyStore.getInstance("AndroidKeyStore")
keyStore.load(null)
var secretKey = keyStore.getKey(keyName, null) as SecretKey?
if(secretKey == null) {
secretKey = generateKey(keyName, this)
}
val mac = Mac.getInstance("HmacSHA256")
mac.init(secretKey)
return mac
}
The key generation itself looks like this
val keyGenerator =
KeyGenerator.getInstance(KEY_ALGORITHM_HMAC_SHA256, "AndroidKeyStore")
keyGenerator.init(KeyGenParameterSpec.Builder(keyAlias, PURPOSE_SIGN)
.setUserAuthenticationRequired(true))
.build()
When I run this I get the fingerprint dialog as expected and on fingerprint scanned the onAuthenticationSucceeded
funtion in the callback gets triggered and the Mac object get's supplied as argument as expected. The problem though is that when I attempt to perform the signing with the Mac object I get a Keystore operation failed
error even though I have successfully scanned my biometrics(which means authentication was successful). Here is the logic for the signing and the error I get.
object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
super.onAuthenticationSucceeded(result)
Log.d(TAG, "Authentication was successful")
val fingerprint = result.cryptoObject?.mac?.doFinal(SALT.toByteArray())
}
}
The error
java.security.ProviderException: Keystore operation failed
at android.security.keystore2.AndroidKeyStoreHmacSpi.engineDoFinal(AndroidKeyStoreHmacSpi.java:241)
at javax.crypto.Mac.doFinal(Mac.java:667)
at javax.crypto.Mac.doFinal(Mac.java:742)
Caused by: android.security.KeyStoreException: Key user not authenticated (internal Keystore code: -26 message: In KeystoreOperation::finish
Caused by:
0: In finish: KeyMint::finish failed.
1: Error::Km(ErrorCode(-26))) (public error code: 2 internal Keystore code: -26)
at android.security.KeyStore2.getKeyStoreException(KeyStore2.java:369)
at android.security.KeyStoreOperation.handleExceptions(KeyStoreOperation.java:78)
at android.security.KeyStoreOperation.finish(KeyStoreOperation.java:128)
at android.security.keystore2.KeyStoreCryptoOperationChunkedStreamer$MainDataStream.finish(KeyStoreCryptoOperationChunkedStreamer.java:228)
at android.security.keystore2.KeyStoreCryptoOperationChunkedStreamer.doFinal(KeyStoreCryptoOperationChunkedStreamer.java:181)
at android.security.keystore2.AndroidKeyStoreHmacSpi.engineDoFinal(AndroidKeyStoreHmacSpi.java:237)
... 13 more