HttpsURLConnectioin的行为与HostnameVerifier和SSLSocketFactory的默认实现

时间:2016-07-03 20:05:29

标签: java ssl httpsurlconnection

我正在尝试理解一段不会覆盖HttpsURLConnection的HostnameVerifier和SSLSocketFactory的代码。当前代码能够使SSL请求正常,这对我来说有点混乱。 HostnameVerifier和SSLSocketFactory类的默认实现如何工作?它是否验证证书CA和主机名,还是一起绕过所有这些检查?

此外,如果请求中包含localhost,是否有任何特殊行为? 网址如下所示 https://localhost:/

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

它将根据JDK jre/lib/security/cacerts的受信任存储中的受信任ca证书或您配置的任何内容检查CA证书。

它还将检查链中的所有证书是否可信,而不仅仅是直接签名者。默认情况下,它不会在线检查已撤销的证书,但您可以在java.security策略文件中启用它。

它还会根据证书检查主机名。 它支持额外的CN和通配符CN。

有关localhost的扩展问题:

localhost只是一个与其他任何主机名相同的主机名。它必须列在证书中。但是你不会找到一个正式的CA给你那个证书,我想: - )

如果您想在localhost上使用真实证书,请使用其他主机名进行解决。如果要运行foo.bar.com的证书,请添加到hosts文件(Win:%WINDOWS%\system32\drivers\etc\hosts,Unix /etc/hosts)行:

127.0.0.1 foo.bar.com

现在启动浏览器并连接到https://foo.bar.com。它将连接到本地服务器并发布SSL加密的HTTP请求。该请求包含URL中的主机名,而不是真实的主机名。

我过度充实:浏览器从服务器接收SSL证书,并将CN与其刚刚调用的主机名进行比较。如果这匹配,它将检查证书是否可以信任(不要在订单上钉我,也许它会先检查trustlevel)。

这是您失败的地方:服务器提供的证书不包含CN localhost,因此客户端将中止连接。在您的情况下,客户端是HttpSSLrequest。

为了让客户相信一切顺利,你可以做两件事: - 伪造主机名,并在cacerts信任库中添加签名CA. - 实现主机名和证书验证器,让您通过。

关于本教程,使用了自签名证书,您必须通过在首次访问时覆盖警告来说服浏览器接受它。