Error after Fingerprint touched on Samsung phones: android.security.KeyStoreException: Key user not authenticated

Viewed 17427

My app uses Android 6.0 Fingerprint API to protect AES key in the Android KeyStore. The stored key can be used only when user is authenticated by fingerprint sensor because the KeyGenParameterSpec is initialized with setUserAuthenticationRequired(true).

When the user touches the sensor I get the initialized Cipher from the callback onAuthenticationSucceeded(Cipher) and I use it for decryption.

This works perfectly except on Samsung phones with Android 6. When I try to use the returned Cipher, Samsung phones sometimes throw android.security.KeyStoreException: Key user not authenticated. So even though the Cipher is returned by the onAuthenticationSucceeded(Cipher) the Android KeyStore thinks user was NOT authenticated by the fingerprint sensor.

It seems that the crash happens rather when the app was not used for longer time. When the app is wormed up all is working correctly usually.

As this error happens randomly and only on Samsung phones... It seems it is caused by some internal timing issue inside the Samsung implementation of Android 6.0 KeyStore and FingerPrint API.

Edit: This issue was also experienced in OnePlus and Acer phones.

9 Answers

I experienced this issue too. In my case, it was due to the fact that I was accidentally starting two concurrent fingerprint authentications by calling FingerprintManager.authenticate() twice. The error disappeared once I removed the second call.

UPDATE: This is a known issue with Android 8.0 https://issuetracker.google.com/issues/65578763

I'm just now seeing this error on Samsung and appears to be caused when adding a new fingerprint. In our code we expect KeyPermenantlyInvalidatedException to be thrown during signature.initSign(). This doesn't occur and the initialized signature is successfully passed inside the CryptoObject to the FingerprintManager. The fingerprint is then successfully verified and onAuthenticationSucceeded is called. The error occurs when attempting to call signature.update(byte[] bytes).

Expected behavior I would believe is that KeyInvalidatedException is actually thrown, but I'm not sure we can ever expect this to be resolved. My solution is to catch it in the onAuthenticationSucceeded side.

@Override
    public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
        Log.d(LOG_TAG, "Device Authentication Succeeded");
        try {
            Signature signature = result.getCryptoObject().getSignature();
            String authData = getAuthData();
            signature.update(authData.getBytes());
            // do something with signature

        } catch (SignatureException e) {
            Log.d(LOG_TAG, e.getMessage());
            if(e.getMessage() != null && e.getMessage().contains("Key user not authenticated")) {
                // handle as if were KeyPermanentlyInvalidatedException
            } else {
                Log.d(LOG_TAG, e.getMessage());
                // handle as regular error
            }
        }
    }

I also had this issue when using Samsung Galaxy S8 with android 8. To solve this problem I try to remove the key from keystore and then generate a new key then I use the new generated key to encrypt and decrypt data

try {
    keyStore.deleteEntry(KEY_ALIAS);
} catch (KeyStoreException e) {
    e.printStackTrace();
}

This seems to be a bug in Android that arises after an update.

I had it on a OnePlus. I removed the device lock from the settings and set it again. After that, the issue was gone.

Related