【问题标题】:What is Keystore?什么是密钥库?
【发布时间】:2014-04-21 17:06:44
【问题描述】:

我得到了:

sun.security.validator.ValidatorException: PKIX path building failed: 
sun.security.provider.certpath.SunCertPathBuilderException: unable to find
valid certification path to requested target
.
.
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.
ValidatorException: PKIX path building failed: sun.security.provider.
certpath.SunCertPathBuilderException: unable to find valid certification 
path to requested target

在搜索如何解决此异常时,我遇到了我不理解的术语Keystore。简而言之,Keystore 是什么?它与 SSL 有什么关系?

【问题讨论】:

  • 简单术语:“在 Java 中,密钥库是安全证书的存储库,可以是授权证书或公钥证书”
  • @BheshGurung 我知道这些文档。但我想在外行。它是什么以及它的需要?它与 SSL 异常有什么关系?
  • @BheshGurung 所以我的localhost 通过 SSL 与远程服务器通信,localhost 应该拥有某种证书?
  • @BheshGurung 您可以在答案中详细说明和解释所有这些。这样会更有好处
  • 没有人回答..奇怪....我今天也遇到了同样的问题...

标签: java ssl keystore


【解决方案1】:
Java 中的

Keystore 可以引用三个东西,具体取决于上下文。 (它们都密切相关,但略有不同。)

  • 密钥库可以是存储私钥、证书和对称密钥的存储库。这通常是一个文件,但也可以通过不同的方式处理存储(例如加密令牌或使用操作系统自己的机制。)

  • KeyStore 也是标准 API 的一部分。它本质上是一种加载、保存和通常与上述“物理”密钥库之一交互的方法。如果您只需要应用程序的 API 抽象,KeyStore 也可以纯粹在内存中。

    如何加载和处理这样的KeyStore 实例取决于支持它的密钥库文件(或其他存储系统)的格式。 Multiple formats 可用。其中一些最常见的是 JKS 和 PKCS#12 (.p12)。

  • “keystore”也可以用作“truststore”的对应物。这就是令人困惑的地方,因为“密钥库”和“信任库”都是密钥库,它们只是用于不同的目的。您可以在this answer 中找到更多详细信息。密钥库用于初始化密钥管理器,而信任库用于初始化信任管理器。来自JSSE reference guide

    • 一个TrustManager判断是否远程认证 凭据(以及连接)应该是可信的。

    • KeyManager 确定要发送的身份验证凭据 到远程主机。

    本质上,用作信任库的密钥库将包含许多您愿意信任的 (CA) 证书:这些是您将用来验证您还不知道和信任的远程证书的信任锚.相比之下,用作密钥库的密钥库将包含您自己的证书及其私钥:这是您将用来向远程方验证您自己的内容(如果需要)。

    有一个与 JRE 捆绑在一起的默认信任库 (/lib/security/cacerts)。没有默认的密钥库,因为它通常对用户来说是一个更明确的步骤。

在 SSL/TLS 的上下文中,密钥库(用作密钥库的密钥库)将是服务器存储其证书和私钥的地方(或者,当使用客户端证书身份验证时,客户端存储其证书和私有密钥钥匙)。信任库(用作信任库的密钥库)将是客户端存储它愿意信任的 CA 的 CA 证书的地方,以便在连接到 SSL/TLS 服务器时能够验证服务器证书(类似地,在服务器端,这也是用于验证客户端证书的 CA 证书的存储位置)。

通常,当您正在连接的服务器的证书无法使用您正在使用的信任库中的任何证书进行验证时,您会遇到错误(“ValidatorException: PKIX path building failed”)。您通常需要在您的信任库中直接在您的信任库中拥有服务器证书(只能在小范围内管理)或用于颁发该服务器证书的 CA 的 CA 证书(或它的链中的证书之一礼物,当有链条时)。

【讨论】:

  • 我只是尝试连接到“google.com”,它给了我成功而没有任何密钥库问题,所以我只是想知道它是如何工作的,为什么 java 在连接到“时没有给出同样的错误” google.com"?
  • 你能帮我处理一下流程吗,比如。 1. 用户尝试连接到一些“https”站点。 2. 服务器拒绝来自已知主机的连接或需要建立的连接。你能以这种方式解释我吗,或者指出任何解释它的链接。
  • @Jayesh 正如我所说,有一个默认的信任库。它包含许多 JRE 已经信任的 CA 证书,包括验证 google.com 的证书。您的第二个问题(关于拒绝连接)与密钥库无关:如果服务器拒绝连接,就是这样,连接被拒绝......什么也没有发生。
  • 谢谢布鲁诺。所以我可以说,当我们尝试访问 https 网站时,服务器返回其证书,然后 java 客户端检查证书是否存在于其密钥库中,如果存在,则客户端到服务器的通信开始使用该密钥进行加密。如果不存在则使用 apache http 客户端,除非我们从远程服务器获取证书并将其存储在我们的 java 密钥库中,否则我们将无法访问 https 网站。我说的对吗?
  • @Jayesh 不完全是。服务器证书不一定需要在信任库中,但至少需要一个可以验证服务器证书的 CA 证书。说“通信开始使用 [证书的] 密钥加密”当然是不正确的:这不是 SSL/TLS 的工作方式,但那是完全不同的事情。一般来说,是的,如果您的信任库不包含可用于验证服务器证书(或 CA 证书本身)的 CA 证书,您将无法连接,除非您还禁用了证书验证你的代码(你不应该这样做)。
【解决方案2】:

简单地说,要建立与 SSL 端点的连接,您必须信任其公共证书。要信任证书,其本身或其颁发者的证书必须在密钥库中。

将密钥库视为一组文件夹或包含证书的数据库/存储库。物理上,它是 JRE 中的一个文件 (/lib/security/cacerts)。

可以使用 JRE 附带的 keytool 命令修改此存储库。一些常用命令见this link。另一种方法是使用 Java 控制面板的证书对话框(这也与 JRE 一起安装):

【讨论】:

  • 您正在使用密钥库概念的一个非常具体的子集。特别是,您在谈论默认信任库。
【解决方案3】:

我也遇到了这个问题,因为我在我的 java 程序未使用的 JDK 中导入了一个证书,所以检查你程序的当前 JDK,然后运行 ​​key tool 命令:

keytool -importcert –trustcacerts -alias [certificate name] -keystore "C:\Program Files\Java\jdk1.7.0_71\jre\lib\security\cacerts" -storepass changeit -file [certificate name].cer

【讨论】:

    猜你喜欢
    • 2016-11-13
    • 2011-09-03
    • 1970-01-01
    • 2011-10-14
    • 2012-12-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    • 2017-08-28
    相关资源
    最近更新 更多