I am developing an Android application in Flutter for which I need to generate a private-public KeyPair through Android's KeyStore (not simply store values in KeyStore but use KeyStore itself to generate these keys). I want these keys to be protected with biometrics/device credentials and for the KeyStore to ask for authentication when using these keys for signing.
Since flutter's secure storage doesn't provide key generating, I am using native code for generating keys through Android's KeyStore.
Native code chunk in MainActivity.kt creating these keys is:
val generator = KeyPairGenerator.getInstance("EC", "AndroidKeyStore")
generator.initialize(KeyGenParameterSpec.Builder("xxx", KeyProperties.PURPOSE_SIGN)
.apply {
setUserAuthenticationRequired(true);
setUserAuthenticationParameters(
0,
KeyProperties.AUTH_DEVICE_CREDENTIAL or KeyProperties.AUTH_BIOMETRIC_STRONG
);
}
.setAlgorithmParameterSpec(
ECGenParameterSpec("secp256r1")
).setDigests(
KeyProperties.DIGEST_NONE,
KeyProperties.DIGEST_SHA256
).build())
var keyPair = generator.generateKeyPair()
This part works fine, keys are generated and stored in KeyStore. However, when I try to use these keys for signing, I get the following exception:
org.bouncycastle.operator.RuntimeOperatorException: exception obtaining signature: android.security.KeyStoreException: Key user not authenticated
I would like to be prompt to authenticate rather then simply get this exception. Is there a way to make natively called code to ask for authentication when accessing keys in KeyStore?