I'm playing around with keys in android and am trying to generate a public/private cryptographic key-pair. Unfortunately I keep getting a 'KeyStoreException: Invalid key blob'.
I'm following the instructions here:
https://developer.android.com/training/articles/keystore.html
Particularly the section entitled 'Generating a New Private Key', which I feel my code copies almost verbatim:
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
keyGen.initialize(
new KeyGenParameterSpec.Builder(
keyName,
KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
.setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512).build()
);
KeyPair pair = keyGen.generateKeyPair();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
The value of keyName
comes from user input, but I have also tried it with the value "abc"
.
The error I'm getting is:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.calebg.claimcreator, PID: 17389
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
at android.view.View.performClick(View.java:6579)
at android.view.View.performClickInternal(View.java:6556)
at android.view.View.access$3100(View.java:777)
at android.view.View$PerformClick.run(View.java:25660)
at android.os.Handler.handleCallback(Handler.java:819)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:6579)
at android.view.View.performClickInternal(View.java:6556)
at android.view.View.access$3100(View.java:777)
at android.view.View$PerformClick.run(View.java:25660)
at android.os.Handler.handleCallback(Handler.java:819)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
Caused by: java.security.ProviderException: Failed to load generated key pair from keystore
at android.security.keystore.AndroidKeyStoreKeyPairGeneratorSpi.loadKeystoreKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:530)
at android.security.keystore.AndroidKeyStoreKeyPairGeneratorSpi.generateKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:478)
at java.security.KeyPairGenerator$Delegate.generateKeyPair(KeyPairGenerator.java:727)
at com.example.calebg.claimcreator.CreateKeyActivity.createKey(CreateKeyActivity.java:76)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:6579)
at android.view.View.performClickInternal(View.java:6556)
at android.view.View.access$3100(View.java:777)
at android.view.View$PerformClick.run(View.java:25660)
at android.os.Handler.handleCallback(Handler.java:819)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
Caused by: java.security.UnrecoverableKeyException: Failed to obtain X.509 form of public key
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStorePublicKeyFromKeystore(AndroidKeyStoreProvider.java:239)
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(AndroidKeyStoreProvider.java:278)
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(AndroidKeyStoreProvider.java:289)
at android.security.keystore.AndroidKeyStoreKeyPairGeneratorSpi.loadKeystoreKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:521)
at android.security.keystore.AndroidKeyStoreKeyPairGeneratorSpi.generateKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:478)
at java.security.KeyPairGenerator$Delegate.generateKeyPair(KeyPairGenerator.java:727)
at com.example.calebg.claimcreator.CreateKeyActivity.createKey(CreateKeyActivity.java:76)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:6579)
at android.view.View.performClickInternal(View.java:6556)
at android.view.View.access$3100(View.java:777)
at android.view.View$PerformClick.run(View.java:25660)
at android.os.Handler.handleCallback(Handler.java:819)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
Caused by: android.security.KeyStoreException: Invalid key blob
at android.security.KeyStore.getKeyStoreException(KeyStore.java:823)
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStorePublicKeyFromKeystore(AndroidKeyStoreProvider.java:241)
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(AndroidKeyStoreProvider.java:278)
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(AndroidKeyStoreProvider.java:289)
at android.security.keystore.AndroidKeyStoreKeyPairGeneratorSpi.loadKeystoreKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:521)
at android.security.keystore.AndroidKeyStoreKeyPairGeneratorSpi.generateKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:478)
at java.security.KeyPairGenerator$Delegate.generateKeyPair(KeyPairGenerator.java:727)
at com.example.calebg.claimcreator.CreateKeyActivity.createKey(CreateKeyActivity.java:76)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:6579)
at android.view.View.performClickInternal(View.java:6556)
at android.view.View.access$3100(View.java:777)
at android.view.View$PerformClick.run(View.java:25660)
at android.os.Handler.handleCallback(Handler.java:819)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
I'm using Android Studio 3.0.1, minSdkVersion 23, targetSdkVersion 26, and I'm testing this on a "Nexus 6 API P" virtual device.
The only other related stackoverflow question I have found (also the only google result) that looks helpful is:
android.security.KeyStoreException: Invalid key blob
However I'm not clear how to apply the answer to my situation and I'm not convinced it is a correct solution in my case (how could the keystore be locked/uninitialised when I only just initialised it? How does catching an exception and trying again solve this problem?).
Can anyone identify what I'm doing wrong?