Android 4.3 KeyStore - 在尝试检索密钥时,链条(chain)== null

8

这篇博客的指导下,我使用以下代码在Android KeyStore中创建和存储一个KeyPair

Context ctx = getApplicationContext();
Calendar notBefore = Calendar.getInstance();
Calendar notAfter = Calendar.getInstance();
notAfter.add(1, Calendar.YEAR);
KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(ctx).
setAlias(RSA_KEYS_ALIAS).setSubject(
  new X500Principal(String.format("CN=%s, OU=%s", 
    getApplicationName(), ctx.getPackageName()))).
setSerialNumber(BigInteger.ONE).
setStartDate(notBefore.getTime()).setEndDate(notAfter.getTime()).build();

KeyPairGenerator kpGenerator;
try {
    kpGenerator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");

    kpGenerator.initialize(spec);
    kpGenerator.generateKeyPair();
} catch (Exception e) {
    showException(e);
}

当我尝试使用此代码从KeyStore中检索公钥时,会抛出一个带有消息chain == nullNullPointerException异常。

public RSAPublicKey getRSAPublicKey() {
    RSAPublicKey result = null;
    try {
        KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
        keyStore.load(null);
        KeyStore.PrivateKeyEntry keyEntry = 
            (KeyStore.PrivateKeyEntry) keyStore.getEntry(RSA_KEYS_ALIAS, null); // --< exception is thrown here
        result = (RSAPublicKey) keyEntry.getCertificate().getPublicKey();
    }
    } catch (Exception e) {
        showException(e);
    }
    return result;
}

与检索私钥的代码相同。

更新:

我将我的代码与Google BasicAndroidKeyStore示例进行了比较。该示例中生成、存储和检索密钥对的机制与我实现的几乎相同。我不明白为什么这段代码在几个月完美运行后停止工作。

任何建议或提示都将不胜感激。

3个回答

4

显然,在Android KeyStore中,名称必须在所有应用程序中唯一。我有另一个应用程序使用了相同的名称来存储其密钥。将通用库更改为在其密钥名称中包括包名称的方式,以创建和使用密钥,问题就解决了...


只是澄清一下 - 问题发生在检索密钥时,而不是生成密钥时。所以当您尝试从与生成密钥的应用程序不同的应用程序中检索密钥时,链 == null 就会发生? - Johnny C
2
我知道这是一篇旧帖子,但你有没有任何参考资料表明别名应该在所有应用程序中唯一? - Amarghosh

3

在我的情况下,我几乎同时调用了多个获取KeyStore的函数。我必须创建一个单一的实例,并在存在时引用它,否则KeyStore.getInstance("AndroidKeyStore")会返回null并引发异常。 为了防止多个异步请求导致崩溃,请使用来自一个KeyStore.getInstance()的存储实例。


我在Android 5上遇到了这个问题。我看到了这个答案,想着...不会吧,肯定不行。所以我尝试了其他所有的答案,但都没有用,最后绝望地回到了这个答案。你知道吗,它完美地解决了我的问题!我猜这个问题在新版本的Android中已经被修复了。不要低估它! - Luke Needham

0
在我的情况下,我试图在生成密钥对之前获取公钥。(在调用generateKeyPair()之前调用getRSAPublicKey()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接