java - Java 中的证书路径发现

标签 java security https x509 pki

我尝试通过 java 内置功能建立 https 连接 (HttpURLConnection)。但我得到这个异常(exception):

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
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
...
...

我的证书链是:

根证书 -> 中间证书 -> Web 服务器证书

根据“路径发现”的含义,使用的证书是正确的。信任 anchor 是根证书,它是在我系统上的 java keystore 中导入的。中间证书不是......但是

  1. 中间证书由我信任的根签名 - 所以我也信任中间证书。
  2. Web 服务器证书使用我信任的中间证书签名(第 1 点)

所以验证必须成功通过?我是不是弄错了什么?

我在某处读到这个:

Browsers can do auto-discovery, server to server doesn't.

但缺少此功能是非常基本的。有明确的方法吗 auto-discovery

** 更新

是的,这就是问题所在,GPI。我很困惑,因为浏览器可以验证服务器证书,但 Java 应用程序不能。 该行为的原因是:

  • 服务器只发送最终证书,而不是整个证书 链;
  • 证书是最近购买的,并且是用相对签名的 新的中级证书;
  • 浏览器有相对最新的证书列表 包括中级证书;
  • java 有相关的非最新证书列表,并且 中级证书不在里面。
  • 浏览器通过中间层验证最终证书 证书 java 无法检查证书链,因为:1。 链条未发送; 2.最终证书的签署人( 中间一个)不是信任 anchor 。

解决方案可能是:

  • 服务器返回整个证书链
  • 要添加到 java 信任库中的中间证书

最佳答案

我相信您已经检查了您的链,因此我们可以理所当然地认为 RootCert 签署了 IntermediateCertIntermediateCert 签署了 ServerCert,具有有效的 X500 名称链和所有...

也就是说,您的逻辑是有效的,即信任 RootCert 就足够了,但不要忘记,为了构建路径,您的客户端必须拥有所有 路径中的证书。

在您的情况下,如果您只信任根证书,则由服务器公布证书链的其余部分(中间和最终)。如果没有人“给”HTTP 客户端中间证书,那么客户端将失败,因为从 RootServer 而不知道 Intermediate 不是可能。

您实际上可以通过使用 -Djavax.net.debug=all 选项启动您的客户端来查看您的服务器证书链是什么。如果链的长度为 1,则您的服务器仅公布最终证书,客户端无法猜测中间证书的存在。

(也可以使用浏览器检查并要求查看服务器证书,但您应该注意,浏览器会向您显示直到信任 anchor 的整个路径,因此如果您想推断服务器链是什么,您必须从该路径中删除浏览器的 anchor )。

在生产服务上,您应该引用您的证书提供商的网站以了解什么被视为根证书(它可能不是最高级别的证书)。这个有效的根应该是您客户端的信任 anchor ,并且任何服务器都应该至少通告链中从路径中最后一个证书(其公用名称是服务器的 DNS 名称)向上的所有其他证书。

关于java - Java 中的证书路径发现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15974516/

相关文章:

java - 如何使用 crypto-js 库在客户端加密消息并在 Java 服务器上解密

Tomcat 是否支持 HTTP/2.0?

c++ - nodeMCU 上的持久 https 连接

java - contains() 按值比较,而不是引用?

java - 如何查询日期范围内的数据库对象?

java - Weblogic - 如何关闭服务器进行维护?

javascript - NODE_TLS_REJECT_UNAUTHORIZED Heroku 应用程序使整个应用程序不安全

PHP 监禁任意代码

c# - 无法使用 https 获取网络响应

java - 从 Java 运行 Maven 目标,而无需在计算机上安装 Maven 可执行文件