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?
Caused by: java.lang.IllegalStateException: could not generate key in keystore
hope 1st exception will solved by following code below:
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 getKeyStore
locked is:After the device is booted, KeyStore will be LOCKED.
com.android.credentials.UNLOCK
intent will startcom.android.settings.CredentialStorage
activity, which, in turn, will show UnlockDialog, prompting for a password.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