14

我有一个PKCS#12文件,我认为它是一个密钥库文件,因为它包含一个密钥条目和一个证书条目

在 Android 中,我看到人们通过以下方式以编程方式安装密钥库(代码来自Android 开发者博客):

byte[] keystore = . . (read from a PKCS#12 keystore)

Intent installIntent = KeyChain.createInstallIntent();
installIntent.putExtra(KeyChain.EXTRA_PKCS12, keystore);
startActivityForResult(installIntent, INSTALL_KEYSTORE_CODE);

我还看到人们以编程方式仅安装包装在密钥库中的证书:

Intent intent = KeyChain.createInstallIntent();
intent.putExtra(KeyChain.EXTRA_CERTIFICATE, cert);
startActivity(intent);

此外,我还看到人们安装了密钥库和包装在密钥库中的证书。例如,本文向我们展示了如何首先安装密钥库,然后以编程方式安装包装在密钥库中的证书。

我真的很困惑什么时候应该只安装密钥库以及什么时候应该只安装证书(包装在密钥库中)?我什么时候应该安装两者?有人可以让我澄清一下吗?

例如,我的密钥库 PKCS#12 文件 (mycert.p12) 包含密钥/证书对,它用于连接到 VPN 服务器。我的 android 客户端何时应安装密钥库中包含的密钥库和证书?客户端何时应仅安装包装在密钥库中的证书?有什么区别 ?我对此感到很困惑。

4

3 回答 3

3

我有一个 PKCS#12 文件,我认为它是一个密钥库文件,因为它包含一个密钥条目和一个证书条目。

正确的。

在 Android 中,我看到人们通过以下方式以编程方式安装密钥库......

这是在您拥有密钥库(即密钥对和证书)时完成的。

我还看到人们以编程方式仅安装包装在密钥库中的证书

这是在您拥有其他人的证书时完成的,通常是自签名证书,该证书不受任何已安装的默认 CA(证书颁发机构)的信任。您永远不必这样做。

因此请注意,您永远不要同时使用相同的证书,因为情况(所有权)不同。永远不会怀疑哪个过程是合适的。如果是您的,请导入密钥库。如果是其他人的,请导入证书。

所有这些东西的最终规范参考是ITU Recommendation X.509

最后,关于您链接的低质量博客文章的一些注释。

统一 ICS 中的密钥存储访问

过去,如果应用程序需要对安全的 SSL Web 服务器进行身份验证,或者通过客户端证书对服务器进行用户身份验证,则通常的做法是维护自己的密钥存储。

这已经是不正确的了。

  1. 要对 Web 服务器进行身份验证,您不需要任何东西,如果它具有 CA 签名的证书。如果它具有自签名证书,则需要将其导入您的truststore

  2. 要向Web 服务器验证自己的身份,您需要一个包含您自己的私钥和证书的密钥库,最好是 CA 签名的证书。否则,服务器必须将您的自签名证书导入其信任库,即上述 (1) 的反面。不要走这条路。自签名证书的麻烦远大于其价值,这没什么,从您为它们支付的价格可以看出。

使用 ICS 钥匙串 API

我们首先使用密钥别名获取私钥和​​证书链,然后创建并验证签名以检查密钥是否实际可用。

完全废话。我们已经有了私钥、公钥和证书。它们已经可以使用了。创建签名并在本地验证它完全是浪费时间。

安装 CA 证书与安装 PKCS#12 文件没有太大区别:您将证书加载到字节数组中,并将其作为附加内容传递给安装意图。

不同之处在于您KeyChain.EXTRA_CERTIFICATE在 CA 证书案例和KeyChain.EXTRA_PKCS12密钥库案例中使用。

于 2016-06-21T05:18:10.753 回答
-1

由于还没有人回答您,我希望我至少可以从您链接的博客文章中澄清一些观点。

过去,如果应用程序需要对安全的 SSL Web 服务器进行身份验证,或者通过客户端证书对服务器进行用户身份验证,则通常的做法是维护自己的密钥存储。

这是这里的两个基本用例:

  • 如果您使用客户端证书进行身份验证(向服务器证明您是授权客户端),那么您只需安装证书。
  • 如果您尝试验证服务器的身份,那么您将需要验证服务器的证书。在这种情况下,您将需要安装一个密钥库(如果您不使用自签名证书,可能是一个链)。密钥库中的私钥将用于验证服务器的证书。

您在问题中的第二段代码旨在创建证书链(当您不使用自签名证书时):

我们首先使用密钥别名获取私钥和​​证书链,然后创建并验证签名以检查密钥是否实际可用。由于我们使用的是自签名证书,因此“链”由单个条目组成,但对于由 CA 签名的证书,您需要在返回的数组中找到实际的最终实体证书。

安装 CA 证书与安装 PKCS#12 文件没有太大区别:您将证书加载到字节数组中,并将其作为附加内容传递给安装意图。

Intent intent = KeyChain.createInstallIntent();
intent.putExtra(KeyChain.EXTRA_CERTIFICATE, cert);
startActivity(intent);

我希望这个解释有帮助!:)

于 2013-11-19T20:59:16.783 回答
-1

对于 android 或任何其他“客户端”,即应用程序,以下保持 -

每当需要验证在 SSL 通信期间服务器发送的证书(或证书链)时,都需要信任库(仅公钥)(在 ssl 通信的情况下,服务器将始终将其证书提供给客户端)。

如果服务器的证书已经由受信任的证书颁发机构签名(这意味着证书已经存在于通常可以在下面找到的 java-runtime-truststore 中$JAVA_HOME/jre/lib/security/cacerts),则不需要此步骤,除非正在使用定制的 SSLContext(这也表示正在使用定制的TrustManager )。

例如,SO 的当前证书由 SHA1-Thumbprint 标识的 DigiCert 签名:5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7 :DC:25 并且可能存在于别名“digicerthighassuranceevrootca”下的“cacerts”信任库中。如果 java 客户端向https://stackoverflow.com发出请求,那么默认情况下,通信不需要任何特定的密钥库或信任库。

当客户端需要对一些正在发布到服务器的数据进行数字签名时,通常需要密钥库(私钥和公钥)。一个常见的例子是 xml-signing,你可以在这里找到提及

如果服务器希望客户端提供自己的认证证书作为双向 ssl 握手的一部分,则它也是必需的。从我遇到的情况来看,这并不常见。

链接:

两种方式 SSL

SO自己的密钥库和信任库帖子

于 2016-06-26T16:54:17.987 回答