我试图通过java内置功能(HttpURLConnection
)建立一个https连接。但我有个例外:
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的keystore中导入。中级证书不是..。但
所以验证必须成功通过吗?我是不是出什么问题了?
在某个地方我读到:
浏览器可以进行自动发现,服务器到服务器则不能。
但是缺少这种功能是非常基本的。有明确的方法做这个自动发现吗?
**最新情况
是的,这就是问题所在,GPI。我很困惑,因为浏览器可以验证服务器证书,但是java应用程序不能。造成这种行为的原因是:
解决办法可以是:
发布于 2013-04-12 15:56:00
我相信你已经检查过你的链子了,所以我们可以想当然的认为RootCert签名了IntermediateCert和IntermediateCert签名了ServerCert,有了有效的X500名称链接等等.
尽管如此,您的逻辑是有效的,信任RootCert就足够了,但是不要忘记,为了构建一个路径,您的客户端必须在它的位置上拥有所有的路径中的证书。
在您的情况下,如果您只信任根证书,那么就由服务器来为证书链的其余部分(中间的和最终的)做广告。如果没有人“给”HTTP客户端中间证书,那么客户端将失败,因为在不知道intermediate是不可能的情况下,它将从Root转到Server。
通过使用-Djavax.net.debug=all
选项启动客户端,您实际上可以看到服务器证书链是什么。如果链的长度为1,那么您的服务器只公布最终证书,并且客户端无法猜测中间证书的存在。
(还可以使用浏览器检查并请求查看服务器证书,但您应该注意,浏览器将显示到信任锚的整个路径,因此,如果您想推断服务器链是什么,就必须将浏览器的锚点从这条路径中移除)。
在生产服务上,您应该参考您的证书提供者的网站来知道什么是根证书(它可能不是最高级的一级证书)。这个有效的根应该是客户端的信任锚,并且任何服务器都应该从路径中的最后一个链接(它的公共名称是服务器的DNS名称)向链中的所有其他证书做广告。
发布于 2013-04-12 15:12:46
为了通过Https进行连接,需要使用HttpsURLConnection对象。不能创建与HttpURLConnection对象的连接。
https://stackoverflow.com/questions/15974516
复制相似问题