Cannot generate key in Android keystore

2019-02-01 21:20发布

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条回答
兄弟一词,经得起流年.
2楼-- · 2019-02-01 21:31

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

查看更多
登录 后发表回答