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 系统 - 保存密钥对?的主要内容,如果未能解决你的问题,请参考以下文章