Java中的证书路径发现 [英] Certificate path discovery in Java

查看:167
本文介绍了Java中的证书路径发现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试通过java内置功能建立https连接( HttpURLConnection )。但是我得到了这个例外:

I try to make an https connection via java build-in functionality for that (HttpURLConnection). But I get this 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服务器证书

使用的证书通过路径发现的含义是正确的。信任锚是Root证书,它在我系统上的java密钥库中导入。中间证书不是......但

The used certificate is correct by the meaning of "Path discovery". The trust anchor is the Root certificate, which is imported in java's keystore on my system. The intermediate certificate is not... BUT


  1. 中间证书由我信任的根签署 - 所以我也信任中间证书。

  2. Web服务器证书是使用中级证书签署的,我相信(第1点)

所以验证必须成功通过?我有什么不对吗?

So the validation has to pass successfully? Do I getting something wrong?

在某处我读到了这个:


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

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

但缺少此功能是非常基本的。是否有明确的方法来执行此操作自动发现

but absence of this functionality is very basic. Are there clear way of doing this auto-discovery?

* * 更新

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

Yes, this was the issue, GPI. I was confused, because browsers could validate the server certificate but java application could not. The cause of that behaviour was:


  • 服务器只发送最终证书,而不是整个证书
    chain;

  • 最近购买的证书是用相对
    的新中间证书签署的;

  • 浏览器相对最新证书清单
    包括中间证书;

  • java有相对不是最新的证书列表,
    中间证书不在里面。

  • 浏览器通过中间
    证书验证最终证书java无法检查证书链,因为:1。
    未发送链; 2.最终证书的签名者(
    中间证书)不是信任锚。

  • the server sends only final certificate, not the whole certificate chain;
  • the certificate was recently bought and it was signed with relatively new intermediate certificate;
  • the browsers have relatively up-to-date list of certificates including the intermediate certificate;
  • java have relative not up-to-date list of certificates, and intermediate certificate was not inside.
  • browsers validate the final certificate over the intermediate certificate java could not check the certificate chain because: 1. the chain was not sent; 2. the signer of final certificate (the intermediate one) was not a trust anchor.

解决方案可能是:


  • 服务器返回整个证书链

  • 要在java信任库中添加的中间证书

推荐答案

我相信你已经检查了你的连锁店,所以我们可以理所当然地认为 RootCert 已签署 IntermediateCert IntermediateCert 已签名的 ServerCert ,其中包含有效的X500名称链接以及所有...

I trust you've already checked your chain, so we can take for granted that RootCert signed IntermediateCert and IntermediateCert signed ServerCert, with valid X500 name chaining and all...

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

That said, your logic is valid that trusting the RootCert is enough, but do not forget that in order to build a path, your client must have in its posesssion all the certificates in the path.

在您的情况下,如果您只信任根证书,那么由服务器决定宣传证书链的其余部分(中间和最终)。如果没有人给HTTP客户端中间证书,那么客户端将从 Root Server 失败,而不知道 Intermediate 可能。

In your case, if you trust the root cert only, then it is up to the server to advertise the rest of the certificate chain (intermediate and final). If nobody ever "gives" the HTTP client the intermediate cert, then the client will fail as going from Root to Server without knowing Intermediate is not possible.

通过使用 -Djavax.net.debug = all 选项。如果链的长度为1,那么您的服务器只会通告最终证书,客户端无法猜测中间证书是否存在。

You can actually see what your server certificate chain is by launching your client with the -Djavax.net.debug=all option. If the chain is of length 1, then your server only advertises the final certificate and there is no way the client can guess that the intermediate cert exists.

(也可以使用浏览器检查并要求查看服务器证书,但是您应该注意浏览器将显示信任锚的整个路径,因此如果要推断服务器链是什么,则必须删除浏览器的锚点超出此路径。)

(One can also check using a browser and asking to see the server certificate, but you should note that the browser will show you the whole path up to the trust anchor, so if you want to infer what the server chain is, you have to remove your browser's anchors out of this path).

在生产服务上,您应该参考您的证书提供商的网站,以了解什么是根证书(可能不是最严重的一级)。这个有效的root应该是你的客户端的信任锚,并且任何服务器都应该至少在路径中的最后一个(通用名称是服务器的DNS名称)中通告链中的所有其他证书。

On a production service, you should refer to your certificate provider's website to know what is to be considered as the root certificate (it might not be the topest level one). This effective root should be your client's trust anchor, and any server should advertise at least all other certs in the chain up from the final one in the path (the one whose common name is the DNS name of the server).

这篇关于Java中的证书路径发现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆