使用 HostnameVerifier 和 SSLSocketFactory 的默认实现的 HttpsURLConnectioin 行为

Behavior of HttpsURLConnectioin with default implementation of HostnameVerifier and SSLSocketFactory

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

此外,如果请求中包含本地主机,是否有任何特殊行为? URL 看起来像这样
https://localhost:/

感谢您的帮助。

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

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

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

关于本地主机的扩展问题:

localhost 和其他主机名一样只是一个主机名。它必须在证书中列出。但是我猜你找不到官方 CA 来给你那个证书:-)

如果你想在本地主机上使用你的真实证书,你可以使用不同的主机名来解决它。如果你想 运行 通过 foo.bar.com 的证书,添加到你的 hosts 文件(Win:%WINDOWS%\system32\drivers\etc\hosts,Unix /etc/hosts)行:

127.0.0.1 foo.bar.com

现在启动浏览器并连接到 https://foo.bar.com。它将连接到您的本地服务器和 post 一个 SSL 加密的 HTTP 请求。该请求包含来自 URL 的主机名,而不是真正的主机名。

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

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

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

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