Android KeyStore 系统 - 保存密钥对?

Posted

技术标签:

【中文标题】Android KeyStore 系统 - 保存密钥对?【英文标题】:Android KeyStore System - Saving a KeyPair? 【发布时间】:2015-08-11 17:59:43 【问题描述】:

我目前正在尝试在我的 android 应用程序中整合一个正常运行的 KeyStore 实现。我目前正在针对 18 的最低 API 进行构建,以便我可以充分利用私有 KeyStore 为我的应用程序。我正在尝试生成n 数量的KeyPair 对象,并将它们保存在KeyStore 中以供以后检索。我看过this question,但它似乎有点过时(2012 年),并没有真正很好地回答任何问题。老实说,我在 Stack Overflow 上发现的大多数问题似乎都已经过时了,例如 here 和 here。

所以我的预期流程是这样的:

    尝试从与适当别名相关的证书中检索公钥。 如果此公钥为空,请创建一个新密钥。 使用KeyPairGenerator.getInstance("RSA", "AndroidKeyStore"); 生成密钥对。

到目前为止,一切都非常简单,并且运行良好。接下来是毛茸茸的地方。

    保存密钥对。通过KeyStore.getInstance("AndroidKeyStore");初始化KeyStore 尝试通过X509V3CertificateGenerator 生成X509Certificate。此证书是自签名的。对于证书,我将签名算法设置为"SHA1WithRSAEncryption"。 最后拨打keyStore.setKeyEntry

对于这最后一步,似乎有两种选择:

keyStore.setKeyEntry(String alias, byte[] key, Certificate[] chain);

keyStore.setKeyEntry(String alias, Key key, char[] password, Certificate[] chain);

我从两者中的第二个开始,但收到了java.security.KeyStoreException: entries cannot be protected with passwords ...。好吧,这很奇怪,为什么会有一种方法可以保证抛出异常?让我们试试 1 号门。

此时,当我调用 setKeyEntry 并将 keyPair.getPrivate().getEncoded() 作为第二个参数传递时,我会收到来自系统的java.security.KeyStoreException: Operation not supported because key encoding is unknown

所以我有点不知所措。像这样的加密对我来说相对较新,所以我希望有人能对 Android KeyStore 系统这个非常令人困惑的情况有所了解。

【问题讨论】:

【参考方案1】:

所以我找到了答案 - 希望这将有助于为未来的用户解决一些问题,因为文档中没有明确说明。

KeyPairGeneratorSpec.Builder 有一个方法 setAlias。生成密钥时,它会自动存储在此别名下的 KeyStore 中。无需额外节省即可使其正常工作。然后,您可以通过使用与 KeyPairGenerator 相同的 String provider 实例化 KeyStore 来轻松检索这些密钥。

【讨论】:

【参考方案2】:

我试图将 PKCS12 文件(比如用户手动下载)导入 AndroidKeyStore。看来

keyStore.setKeyEntry(String alias, byte[] key, Certificate[] chain);

AndroidKeyStore 没有实现,它总是抛出以下异常:

KeyStoreException("Operation not supported because key encoding is unknown")

参考: https://android.googlesource.com/platform/frameworks/base.git/+/android-5.1.1_r19/keystore/java/android/security/AndroidKeyStore.java

@Override
    public void engineSetKeyEntry(String alias, byte[] userKey, Certificate[] chain)
            throws KeyStoreException 
        throw new KeyStoreException("Operation not supported because key encoding is unknown");
    

所以,我尝试使用

keyStore.setKeyEntry(String alias, Key key, char[] password, Certificate[] chain);

通过将密码作为空值传递。对我来说效果很好。

【讨论】:

以上是关于Android KeyStore 系统 - 保存密钥对?的主要内容,如果未能解决你的问题,请参考以下文章

Android Keystore 对称-非对称加密

Android密钥库系统KeyStore

Android | 安全码SHA1

Android查看应用签名方法

android sdk 如何重新生成debug.keystore

Android java更新Android KeyStore中的证书和私钥