证书路径发现在Java中(Certificate path discovery in Java)

2019-08-22 08:40发布

我尽量让通过Java内置的功能,为HTTPS连接( HttpURLConnection )。 但是,我得到这个异常:

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)
...
...

我的证书链是:

Root certificate -> Intermediate certificate -> Web server certificate

所使用的证书是由“路径发现”的含义是正确的。 该信任锚的根证书,这是Java的密钥库导入我的系统上。 中间证书是不是... BUT

  1. 所以我在中间太信任 - 中级证书是由根,谁我相信签署。
  2. Web服务器证书与中级证书,我相信签署(点1)

因此在验证时必须顺利通过? 难道我得到什么了吗?

我曾读到这样的:

浏览器可以做到自动发现,服务器对服务器没有。

但没有这个功能是非常基本的。 是否有这样做的明确的方式自动发现 ?

*更新

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

  • 服务器只发送最后的证书,而不是整个证书链;
  • 该证书是最近买的,它与相对较新的中级证书签名;
  • 浏览器具有相对向上最新证书,包括中间证书的列表;
  • java的具有相对没有达到最新的证书列表,和中间证书是不是里面。
  • 浏览器验证在该中间证书的Java最终证书可能不检查,因为证书链:1.未发送的链; 2.最终证书(中间一个)的签名者不是信任锚。

该解决方案可以是:

  • 服务器返回的整个证书链
  • 在Java信任存储要添加的中间证书

Answer 1:

我相信你已经检查您的链条,所以我们可以想当然地认为RootCert签署IntermediateCertIntermediateCert签署ServerCert,凭有效X500名称链接和所有...

这就是说,你的逻辑是有效的是信任RootCert就足够了,但不要忘记,为了建立一个路径,您的客户端必须在其posesssion路径中的所有证书。

在你的情况,如果你信任的根证书而已,那么它是由服务器通告证书链(中间和最后)的其余部分。 如果没有人“给出”的HTTP客户端的中间证书,则客户端将无法从服务器不知道中间是不可能的。

实际上,你可以看到你的服务器证书链是由与启动你的客户什么-Djavax.net.debug=all选项。 如果链的长度为1,那么你的服务器只通告最终的证书,也没有办法让客户端可以猜测的是,中间证书存在。

(你也可以检查使用的浏览器,并要求见服务器证书,但你应该注意的是,浏览器会告诉你整个路径到信任锚,所以如果你想推断出服务器链是什么,你必须删除浏览器的锚了这条道路的)。

在生产服务,你应该参考您的证书提供商的网站,知道什么是被视为根证书(它可能不是一个topest水平)。 这种有效的根应该是你的客户的信任锚,任何服务器应在路径中最后一个(公共名是服务器的DNS名称的)广告的环比上涨至少所有其他证书。



Answer 2:

为了通过HTTPS连接,你需要使用一个HttpsURLConnection的对象。 不能创建与HttpURLConnection类对象的连接。



文章来源: Certificate path discovery in Java