I have the following lines to get the private key from key store on Android
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
// generating key pair code omitted
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) this.keyStore.getEntry("alias", null);
Everything works fine except that when the OS upgrades from Android 5.1.1 to Android 6.0.1, the 3rd line will throw java.security.UnrecoverableKeyException: Failed to obtain information about private key
for very first execution. But it will work fine again afterward. Now my workaround is to execute the line for 2 times. At the same time, I am also wondering if there is better way to avoid the exception.
Update
The exception trace
W/System.err﹕ java.security.UnrecoverableKeyException: Failed to obtain information about private key
W/System.err﹕ at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStorePublicKeyFromKeystore(AndroidKeyStoreProvider.java:217)
W/System.err﹕ at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(AndroidKeyStoreProvider.java:253)
W/System.err﹕ at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStorePrivateKeyFromKeystore(AndroidKeyStoreProvider.java:263)
W/System.err﹕ at android.security.keystore.AndroidKeyStoreSpi.engineGetKey(AndroidKeyStoreSpi.java:93)
W/System.err﹕ at java.security.KeyStoreSpi.engineGetEntry(KeyStoreSpi.java:372)
W/System.err﹕ at java.security.KeyStore.getEntry(KeyStore.java:645)
W/System.err﹕ at com.example.keystoretest.MainActivity.onCreate(MainActivity.java:113)
W/System.err﹕ at android.app.Activity.performCreate(Activity.java:6251)
W/System.err﹕ at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
W/System.err﹕ at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
W/System.err﹕ at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
W/System.err﹕ at android.app.ActivityThread.-wrap11(ActivityThread.java)
W/System.err﹕ at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:102)
W/System.err﹕ at android.os.Looper.loop(Looper.java:148)
W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5417)
W/System.err﹕ at java.lang.reflect.Method.invoke(Native Method)
W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
W/System.err﹕ Caused by: android.security.KeyStoreException: Invalid key blob
W/System.err﹕ at android.security.KeyStore.getKeyStoreException(KeyStore.java:632)
W/System.err﹕ at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStorePublicKeyFromKeystore(AndroidKeyStoreProvider.java:218)
W/System.err﹕ ... 18 more
When this error happens and why?
Ans: When loading Android keys and storing public key from Keystore, this error may happen if the state is locked or uninitialized.
Error generating portion code is given below:
KeyStore has 10 response code. They are
State Checking code is given below:
Resource Link:
UPDATE:
From your error log, it is now clear that
this is the main issue which is caused when user tries to UNLOCK from LOCK/UNINITIALIZED. It is by default defined as 30 secs for timing. This problem is it's API related implementation issue.
For encryption/decryption some data with the generated key only works if the user has just authenticated via device credentials. The error occurs from
Actual error is thrown from here. Your error is generated from
InvalidKeyException
.Solution:
You have to remove the
InvalidKeyException
class from the catch argument. This will still allow you to check forInvalidKeyException
. After checking you have to try for second time with code so that the problem is not shown in eye but doing 2 times checking it may solve your issue. I have not tested the code but should be like below:Resource Link: