Search code examples
androidandroid-keystoreandroid-fingerprint-apikey-generator

Android Keystore that requires authentication, not unlocked by fingerprint but by pin only?


EDIT: This appears to be device specific. I have one emulator that this occurs on and one that it works how i'd expect. Would love a universal answer, but maybe there isn't one?

Experiencing something which I think is a little odd. I've created an AndroidKeyStore that requires user credentials. Therefore when I try to encrypt using that key, I get the exception "UserNotAuthenticatedException", perfect.

I then launch the confirm device credentials:

val keyguardManager = requireContext().getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
        val intent = keyguardManager.createConfirmDeviceCredentialIntent(("Test"),"This is the description")
        if (intent != null)
            startActivityForResult(intent, AUTHENTICATION_REQUEST)

This works perfect, onActivityResult after unlocking with either the PIN or the fingerprint, I get back a success state. However, when I now try to go and use the keystore again:

If I had used my PIN on the Credentials Screen, I'm able to use the keystore no problem.

If I had used my fingerprint on the Credentials Screen, it throws a "UserNotAuthenticatedException" again. And I basically can go in an infinite loop with the fingerprint. Am I missing a setting or something that allows the fingerprint to be used? I'm able to unlock the phone itself no problem with the fingerprint, its just this keystore that I can't get through.

    val keyGenerator =
                    KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
                val builder = KeyGenParameterSpec.Builder(
                    alias,
                    KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
                )
     builder.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                        .setUserAuthenticationRequired(userAuthenticationRequired)
                        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                        builder.setUserAuthenticationValidityDurationSeconds(
                            userAuthenticationValidityDurationSeconds
                        )
keyGenerator.init(builder.build())
            keyGenerator.generateKey()

Thanks


Solution

  • This turned out to be a device specific bug. For whatever reason, the test device I had and was using didn't allow for the fingerprint to unlock it under these circumstances. It worked as expected with other devices.