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,我不这么认为。答案相同,但方式不同。顺便说一句,我添加了链接。谢谢