I am using AndroidKeystore in my app to store a secret key, which has
.setUserAuthenticationRequired(true)
.setUserAuthenticationValidityDurationSeconds(30*60)
I generate and store the secret key when user signup. And then to consume the key, I
methodToConsumeSecretKey(){
....
KeyStore keyStore = KeyStore.getInstance(ANDROID_KEY_STORE);
keyStore.load(null);
KeyStore.SecretKeyEntry secretKeyEntry;
secretKeyEntry = (KeyStore.SecretKeyEntry) keyStore.getEntry(getSecretKeyAlias(), null);
final SecretKey secretKey = secretKeyEntry.getSecretKey();
final Cipher cipher = getCipherInstance();
byte[] iv = BaseEncoding.base64().decode(<stored iv>);
cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv));
}
The expected behaviour for this code is:
It'll throw UserNotAuthenticatedException
when the user has not authenticated in last 30 minutes (the duration that I am passing to setUserAuthenticationValidityDurationSeconds
).
I am listening for that exception and when that's thrown, I ask to authenticate the user using:
Intent intent = keyguardManager.createConfirmDeviceCredentialIntent("Unlock", null);
if (intent != null) {
startActivityForResult(intent, REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS);
}
and then onActivityResult()
, if I receive RESULT_OK
, I try to execute methodToConsumeSecretKey()
again.
Now, it works in most cases. But I've observed for some of our customers, methodToConsumeSecretKey()
repeatedly throws UserNotAuthenticatedException
even if the user has authenticated successfully. So, they are kind of stuck into a loop where they keep authenticating and OS keeps throwing this exception.
I haven't observed any pattern in the devices or android versions of these customers. These are the number of users per android version:
[{"version":"8.1.0","count":"8119"},{"version":"8.0.0","count":"3384"},{"version":"7.0","count":"2882"},
{"version":"9","count":"1645"},{"version":"6.0.1","count":"1281"},{"version":"6.0","count":"1063"},
{"version":"7.1.2","count":"931"},{"version":"7.1.1","count":"880"}]
.
Also, this is not happening for particular manufacturer. These users are on Xiaomi
, OnePlus
, Lenovo
, Motorola
in decreasing order of count. There are other manufacturers too.
I've gone through android issuetracker bugs like this and this, and questions like : this and this.
But still, haven't been able to arrive at a conlusion what might be causing this.
One guess is that it's throwing UserNotAuthenticatedException
in cases where it should throw keypermanentlyinvalidatedexception
(as stated in the second question and first bug linked above), but still not sure of that.
P.S. I've personally faced this issue in one of our test devices. I couldn't figure out why it was happening. I removed the device lock from the settings and set it again. After that, the issue was gone.
I strongly feel this is a bug in android os and have created an issue for this here : https://issuetracker.google.com/issues/119944680.
Please star the issue if you are facing this.