Android KeyStore: Is it possible to set up a custom password for authenticate the Key user so that they can use the key from the KeyStore?

Viewed 167

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
}
0 Answers
Related