Android KeyStore系统 - 保存KeyPair?

时间:2015-08-11 17:59:44

标签: java android encryption android-keystore

我目前正在尝试在我的Android应用程序中整合一个正常运行的KeyStore实现。我目前正在建立最低API为18,以便我可以充分利用我的应用程序的私有KeyStore。我正在尝试生成nKeyPair个对象,并将它们保存在KeyStore中以便以后检索。我看过this question,但它看起来有点过时(2012年)并没有真正回答任何问题。老实说,我在Stack Overflow上发现的大部分问题似乎都过时了,例如herehere

所以我的目标是:

  1. 尝试从与相应别名相关的证书中检索公钥。
  2. 如果此公钥为null,请创建一个新密钥。
  3. 利用KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
  4. 生成密钥对。
  5. 到目前为止,所有事情都非常直接,并且工作正常。接下来是毛茸茸的地方。

    1. 保存密钥对。通过KeyStore.getInstance("AndroidKeyStore");
    2. 初始化KeyStore
    3. 尝试通过X509Certificate生成X509V3CertificateGenerator。此证书是自签名的。对于证书,我将签名算法设置为"SHA1WithRSAEncryption"
    4. 最后,请致电keyStore.setKeyEntry
    5. 对于最后一步,似乎有两种选择:

      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系统这种令人困惑的情况有所了解。

2 个答案:

答案 0 :(得分:11)

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

KeyPairGeneratorSpec.Builder有方法setAlias。生成密钥时,它会自动存储在此别名下的KeyStore中。没有额外的节约需要发生才能使其发挥作用。然后,您可以通过使用与KeyPairGenerator相同的String provider实例化KeyStore来轻松检索这些键。

答案 1 :(得分:3)

我试图将一个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);

将密码传递为null。它对我来说很好。