【问题标题】:Behavior of HttpsURLConnectioin with default implementation of HostnameVerifier and SSLSocketFactoryHttpsURLConnectioin 的行为与 HostnameVerifier 和 SSLSocketFactory 的默认实现
【发布时间】:2016-07-03 20:05:29
【问题描述】:

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

另外,如果请求中包含本地主机,是否有任何特殊行为? URL 如下所示
https://localhost:/

感谢您的帮助。

【问题讨论】:

    标签: java ssl httpsurlconnection


    【解决方案1】:

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

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

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

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

    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 与它刚刚调用的主机名进行比较。如果匹配,它将检查证书是否可以信任(不要将我钉在订单上,也许它会先检查信任级别)。

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

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

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

    【讨论】:

    • 我应该寻找什么配置?我不确定 JDK 的默认信任存储设置在哪里。
    • "它支持额外的 CN 和通配符 CN。"。通配符 CN 是什么意思。 localhost 是否被视为通配符 CN?正在发送的请求使用本地主机,但服务器发回的证书中没有“本地主机”。
    • 通配符证书包含一个星号,适用于该域的所有子域:*.foo.com 适用于 bar.foo.combaz.foo.com 等。如果您想使用 localhost,请将其添加到证书中.看我的回答。
    • 非常感谢您的帮助。现在很有意义。但是,我正在阅读这篇文章,并且有一次它说您应该能够使用localhost:8443 进行连接。为什么 localhost 应该在这里工作?证书没有对吗? te.systemautomation.com/docs/ssl-howto.html#Configuration
    • 客户端首先检查主机名。服务器最初只提供证书
    猜你喜欢
    • 1970-01-01
    • 2015-12-22
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    • 2020-12-18
    • 2023-03-10
    • 1970-01-01
    相关资源
    最近更新 更多