I'm building a simple app containing notes encrypted with the KeyStore key (for the purposes of security classes). To view the notes, the user must authenticate either with a fingerprint or a password set in the application. My problem is that when using password login I get "android.security.KeyStoreException: Key user not authenticated" error. I found that I can work around this problem by setting setUserAuthenticationRequired (false), but as far as I know it's not a good technique. I wonder if it is possible to set a password to access the key, which, if correct, authenticates our use of the key from the KeyStore. I have tried to achieve this by using the setKeyEntry() function, but I get the error "java.security.KeyStoreException: entries cannot be protected with passwords" . Can someone explain to me how to do it correctly (if of course it is possible?). Below is the code on how I'm generating and getting my key.
fun getOrCreateSecretKey(): SecretKey {
// if key already exists
val keyStore = KeyStore.getInstance(ANDROID_KEYSTORE)
keyStore.load(null) // Keystore must be loaded before it can be accessed
keyStore.getKey(YOUR_SECRET_KEY_NAME, "testPassword".toCharArray())?.let { return it as SecretKey }
// if key doesn't exist
val paramsBuilder = KeyGenParameterSpec.Builder(
YOUR_SECRET_KEY_NAME,
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
)
paramsBuilder.apply {
setBlockModes(ENCRYPTION_BLOCK_MODE)
setEncryptionPaddings(ENCRYPTION_PADDING)
setKeySize(KEY_SIZE)
setUserAuthenticationRequired(false)
}
// generating key
val keyGenParams = paramsBuilder.build()
val keyGenerator = KeyGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_AES,
ANDROID_KEYSTORE
)
keyGenerator.init(keyGenParams)
val myKey = keyGenerator.generateKey()
// setting entry password
keyStore.setKeyEntry(YOUR_SECRET_KEY_NAME, myKey, "testPassword".toCharArray(), null)
return myKey
}