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

烈酒焚心 提交于 2019-11-27 13:08:51

问题


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.


回答1:


Setting KeyGenParameterSpec.setUserAuthenticationRequired(false) can be a potential security issue. The above error should be handled similar to KeyPermanentlyInvalidatedException. KeyPermanentlyInvalidatedException is thrown on Cipher initialization if new fingerprints are added after your SecretKey is created. But, if the Cipher is initialized before the new fingerprints are added, you'll get the above KeyStoreException for Key User not authenticated, when you're trying to encrypt or decrypt with that Cipher.

It's easy to reproduce this error. While your app's fingerprint verification screen is in the background, try adding a new fingerprint. Now switch back to the app, and enter the fingerprint, the encryption or decryption methods would throw this error. I could resolve this issue by catching the exception and treating it the same way as KeyPermanentlyInvalidatedException.




回答2:


Do NOT listen to the "setUserAuthenticationRequired(false)"

I have been able to reproduce this on Samsung by listening twice. What I think is happening is, you listen twice, authenticate on the one call, but reference it through another.

add Logs and check that you only start listening for fingerprint once and once only.




回答3:


As I don't expect that the mentioned manufacturers will fix this issue soon, I've resolved it by setting the KeyGenParameterSpec.setUserAuthenticationRequired(false) for Samsung, OnePlus, Asus and some other devices.




回答4:


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.




回答5:


I also had this issue when using Samsung Galaxy S8 with android 8. For solve this problem I just remove key from keystore and generate new after that use new key for encrypt and decrypt data

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



回答6:


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
            }
        }
    }



回答7:


I also had this issue when using RSA and could solve it by creating a copy of the public key as soon as i want to encrypt some data.

// create a copy of the public key -> workaround for android.security.KeyStoreException: Key user not authenticated
val publicKey = KeyFactory
    .getInstance("RSA")
    .generatePublic(X509EncodedKeySpec(keyPair.public.encoded))

// encrypt with the public key
val cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding")
cipher.init(Cipher.ENCRYPT_MODE, publicKey)
val encryptedData = cipher.doFinal(data)



回答8:


It works on my Samsung Galaxy S8 by explicitly setting the authenticated key's validity duration:

setUserAuthenticationValidityDurationSeconds(10);

This however makes it technically possible to use the key multiple times within that timespan without requiring further user authentication.

Personally I don't think it's such a big risk.

I have not tested encrypting large streams that may take several seconds to complete using these protection measures. I wonder what happens if the encryption task takes longer than what the validity duration allows.




回答9:


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.



来源:https://stackoverflow.com/questions/36043912/error-after-fingerprint-touched-on-samsung-phones-android-security-keystoreexce

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!