Cannot generate key in Android keystore
Asked Answered
M

1

23

We are currently experiencing an issue where sometimes when a user installes our app, the app tries to access and generate a key in the keystore but the keystore throws this exception:

Caused by: java.lang.IllegalStateException: could not generate key in keystore
        at android.security.AndroidKeyPairGenerator.generateKeyPair(AndroidKeyPairGenerator.java:100)
        at java.security.KeyPairGenerator$KeyPairGeneratorImpl.generateKeyPair(KeyPairGenerator.java:275)

We think it has to do with the unlock pattern off the phone does not unlock the keystore, and/or a device administrator locks the keystore.

This is how the keystore is created and how the keys are generated:

public SecretKeyWrapper(Context context, String alias) throws GeneralSecurityException, IOException {
    mCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    final KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
    keyStore.load(null);

    if (!keyStore.containsAlias(alias)) {
        generateKeyPair(context, alias);
    }

    final KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias, null);
    mPair = new KeyPair(entry.getCertificate().getPublicKey(), entry.getPrivateKey());
}

private static void generateKeyPair(Context context, String alias) throws GeneralSecurityException {
    final Calendar start = new GregorianCalendar();
    final Calendar end = new GregorianCalendar();
    end.add(Calendar.YEAR, 100);

    final KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(context)
            .setAlias(alias)
            .setSubject(new X500Principal("CN=" + alias))
            .setSerialNumber(BigInteger.ONE)
            .setStartDate(start.getTime())
            .setEndDate(end.getTime())
            .build();

    final KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
    gen.initialize(spec);
    gen.generateKeyPair();
}

Does anyone know how to:

  • Lock the keystore as an device administrator?
  • Unlock the keystore when it has been locked by a device administrator?
  • Or reproduce this issue in another way?
Megavolt answered 9/6, 2015 at 15:43 Comment(2)
Show the code of how you are creating the Keystore.Polychaete
have you found a solution?Pliers
P
11

Caused by: java.lang.IllegalStateException: could not generate key in keystore

hope 1st exception will solved by following code below:

KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
KeyStore.Entry entry = ks.getEntry(alias, null);

ks.getEntry(alias, new KeyStore.PasswordProtection(password))

Unlock the keystore when it has been locked by a device administrator:

KeyStore can appear locked not only on pre-ICS devices. The simplest way to get KeyStore locked is:

  1. Initialize KeyStore by setting KeyGuard (pattern, pin, or password on the Screen Lock)
  2. Add keys or whatever you store in the KeyStore
  3. Go to Settings > Security and change Screen Lock to something "not secure", for example, Slide.
  4. Reboot your device.

After the device is booted, KeyStore will be LOCKED. com.android.credentials.UNLOCK intent will start com.android.settings.CredentialStorage activity, which, in turn, will show UnlockDialog, prompting for a password.

 * KeyStore: LOCKED
 * KeyGuard: OFF/ON
 * Action:   old unlock dialog
 * Notes:    assume old password, need to use it to unlock.
 *           if unlock, ensure key guard before install.
 *           if reset, treat as UNINITALIZED/OFF

You can just generate a master key and store it as a private file, other apps won't be able to read it, so you'll be fine on non-rooted devices. This is the approach recommended on the Android Developers Blog:: http://android-developers.blogspot.jp/2013/02/using-cryptography-to-store-credentials.html

Same question answer: Android android.credentials.UNLOCK Initializing keystore without password

Pennyweight answered 6/11, 2016 at 8:45 Comment(3)
Thanks for your answer Jamil. I can't see however how calling the KeyStore.getEntry(...) method with a password makes sense given that the KeyStore entry was not created with a password (see the KeyPairGenerator. generateKeyPair() method invocation in the question). Please explain.Dovecote
This answer is copied from this other answer https://mcmap.net/q/586554/-android-android-credentials-unlock-initializing-keystore-without-password. An honest approach should have been linking that answer giving credit to the author.Exudate
@Exudate I don't think so. Same answer but different way. Btw I added link. Thanks.Pennyweight

© 2022 - 2024 — McMap. All rights reserved.