无法在Android密钥库中生成密钥

时间:2015-06-09 15:43:07

标签: 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 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();
}

有谁知道如何:

  • 将密钥库锁定为设备管理员?
  • 在设备管理员锁定密钥库时解锁密钥库?
  • 或以其他方式重现此问题?

1 个答案:

答案 0 :(得分:11)

@foreach (var question in Model.Assessment.Questions) { <li class="row"> <div class="span9"> @Html.Raw(question.QuestionText) </div> <div class="span3"> @Html.Raw(Model.Assessment.chosenAnswers.FirstOrDefault(a => a.QuestionID == question.QuestionID)) </div> </li> }

希望第一个例外将通过以下代码解决:

Caused by: java.lang.IllegalStateException: could not generate key in keystore

在设备管理员锁定密钥库时解锁密钥库:

KeyStore ks = KeyStore.getInstance("AndroidKeyStore"); ks.load(null); KeyStore.Entry entry = ks.getEntry(alias, null); ks.getEntry(alias, new KeyStore.PasswordProtection(password)) 不仅可以锁定在预ICS设备上。获取KeyStore的最简单方法是:

  1. 通过设置KeyGuard(屏幕锁定上的图案,图钉或密码)来初始化KeyStore
  2. 添加密钥或您存储在KeyStore中的任何内容
  3. 转到设置&gt;安全和更改屏幕锁定某些内容&#34;不安全&#34;,例如,幻灯片。
  4. 重启设备。
  5. 设备启动后,KeyStore将被锁定。 KeyStore意图会启动com.android.credentials.UNLOCK活动,然后会显示UnlockDialog,提示您输入密码。

    com.android.settings.CredentialStorage

    您可以生成主密钥并将其存储为私人文件,其他应用程序无法读取,因此您可以在非root设备上使用。这是Android开发人员博客上推荐的方法:: http://android-developers.blogspot.jp/2013/02/using-cryptography-to-store-credentials.html