我正在尝试理解一段不会覆盖HttpsURLConnection的HostnameVerifier和SSLSocketFactory的代码。当前代码能够使SSL请求正常,这对我来说有点混乱。 HostnameVerifier和SSLSocketFactory类的默认实现如何工作?它是否验证证书CA和主机名,还是一起绕过所有这些检查?
此外,如果请求中包含localhost,是否有任何特殊行为? 网址如下所示 https://localhost:/
感谢您的帮助。
答案 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. - 实现主机名和证书验证器,让您通过。
关于本教程,使用了自签名证书,您必须通过在首次访问时覆盖警告来说服浏览器接受它。