Java 无法在Android密钥库中生成密钥
我们目前遇到一个问题,有时当用户安装我们的应用程序时,应用程序会尝试访问并生成密钥库中的密钥,但密钥库会引发此异常:Java 无法在Android密钥库中生成密钥,java,android,security,keystore,android-keystore,Java,Android,Security,Keystore,Android Keystore,我们目前遇到一个问题,有时当用户安装我们的应用程序时,应用程序会尝试访问并生成密钥库中的密钥,但密钥库会引发此异常: Caused by: java.lang.IllegalStateException: could not generate key in keystore at android.security.AndroidKeyPairGenerator.generateKeyPair(AndroidKeyPairGenerator.java:100) at
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)
我们认为这与解锁模式有关,手机不解锁密钥库,和/或设备管理员锁定密钥库
这是创建密钥库和生成密钥的方式:
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();
}
有人知道如何:
- 以设备管理员身份锁定密钥库
- 当密钥库已被设备管理员锁定时,是否解锁该密钥库
- 还是以另一种方式重现这个问题
原因:java.lang.IllegalStateException:无法在密钥库中生成密钥
希望通过以下代码解决第一个异常:
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
KeyStore.Entry entry = ks.getEntry(alias, null);
ks.getEntry(alias, new KeyStore.PasswordProtection(password))
当设备管理员锁定密钥存储库时,将其解锁:
KeyStore
不仅在ICS之前的设备上显示为锁定。锁定密钥库的最简单方法是:
通过设置KeyGuard(模式、pin或屏幕锁上的密码)初始化密钥库
添加密钥或存储在密钥库中的任何内容
进入设置>安全,并将屏幕锁定更改为“不安全”,例如幻灯片
重新启动设备
设备启动后,密钥库将被锁定com.android.credentials.UNLOCK
intent将启动com.android.settings.CredentialStorage
活动,该活动将依次显示UnlockDialog,提示输入密码
* 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
您只需生成一个主密钥并将其存储为私有文件,其他应用程序将无法读取它,因此您在非根设备上也可以。这是Android开发者博客上推荐的方法:
相同的问题答案:显示如何创建密钥库的代码。找到解决方案了吗?感谢您的回答。但是,我看不出使用密码调用KeyStore.getEntry(…)
方法有什么意义,因为KeyStore条目不是使用密码创建的(请参阅问题中的KeyPairGenerator.generateKeyPair()
方法调用)。请解释。这个答案是从另一个答案复制过来的。一个诚实的方法应该是把这个答案联系起来,以表扬作者。@Manzotin,我不这么认为。答案相同,但方式不同。顺便说一句,我添加了链接。谢谢