Cannot generate key in Android keystore

9.1k views Asked by At

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?
1

There are 1 answers

3
Jamil Hasnine Tamim On

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