1

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?

Caleb
  • 454
  • 5
  • 13

3 Answers3

1

I have the same issue while trying to run my app on Android-P, I think they made some changes on the keystore See the preview, I was wondering if your physical device was running with Android P?

0

I tried this on a real device and it works. Don't know why, but for some reason the Android emulator is unable to create keys according to the Android documentation.

Caleb
  • 454
  • 5
  • 13
  • It crashes on a small number of devices. [See this post on stackoverflow](https://stackoverflow.com/questions/44469020/androidkeystore-keypairgenerator-crashes-on-small-number-of-devices) I encounter this error on OnePlus 2 devices and the Android P simulator. – Oliver Kranz Apr 18 '18 at 10:58
  • Even the sample app [BasicAndroidKeyStore](https://github.com/googlesamples/android-BasicAndroidKeyStore) advised in the [Keystore Android documentation](https://developer.android.com/training/articles/keystore.html) crashes. – Oliver Kranz Apr 18 '18 at 11:41
-1

You may try the following code, it is based on AES-128 encryption algo.

public void RandomKey(View view)
{

    int[] Keys = new int[16];
    String keyString ="";


    //reset the secret key into null
    Secret_Key="";
    SecretKey.setText(Secret_Key);

    try
    {
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(128); // 128 bit
        javax.crypto.SecretKey secretKey = keyGen.generateKey(); //generate secret key
        SKey= secretKey.getEncoded();
        // to display
        for (int i = 0; i < 16; i++)
        {

            Keys[i] = SKey[i] & 0x000000FF;//convert byte to integer
            keyString = Integer.toHexString(Keys[i]);

            if (keyString.length() < 2)
            {
                keyString="0"+keyString;
            }
            //Log.d("keys are"," "+i+keyString);
            Secret_Key = Secret_Key + " " + keyString;
        }

        SecretKey.setAllCaps(true);
        SecretKey.setText(Secret_Key);
    }

for more complete program, you can refer to this: https://github.com/aliakbarpa/AES-128_for_Android

AliAP
  • 1
  • Thanks AliAP, that gives me a SecretKey, but not a KeyPair. Also the reason I was trying to follow the android guide is that it talks about storing keystores in a place within the phone that is not easy to extract. I wonder what I need to do to ensure keys generated by Java are stored in this way? – Caleb Mar 21 '18 at 03:41