【问题标题】:SSLHandshakeException: hostname in certificate didn't matchSSLHandshakeException:证书中的主机名不匹配
【发布时间】:2013-10-18 00:27:00
【问题描述】:

我正在编写一个系统,该系统必须向具有自签名证书的服务器(一个名为 ARX 的第三方程序,当前在开发期间在 localhost 上运行)进行多部分发布。

我试图找到它的证书,但只能找到三个不同的 jks 文件; server.jksservertrust.jksserverca.jks

我尝试将System.setProperty("javax.net.ssl.trustStore", "Program Files\\<path>\\jksfile") 与每个 jks 文件一起使用。然而;当我这样做时,我收到以下错误: 证书中的主机名不匹配: !=

我在 stackoverflow 上浏览了很多类似的问题,试图了解如何解决这个问题,但我无法解决我的问题。

有什么建议吗?非常感谢所有帮助。

【问题讨论】:

  • 我曾经写过一个问题,描述了我在实施安全连接过程中经历的所有阶段。看看hostNameVerifier 部分 - 它可能会对您有所帮助:stackoverflow.com/questions/15544116/…

标签: java security ssl apache-httpclient-4.x


【解决方案1】:

证书本身似乎受信任,因此您的 javax.net.ssl.trustStore 设置有效,但主机名不匹配。

主机名匹配是根据客户端如何识别它尝试访问的主机来完成的。如果它试图访问https://localhost/,则证书必须对localhost 有效。如果它试图访问https://something-else.example,那么证书必须对something-else.example 有效,即使localhostsomething-else.example 是同一台机器。

证书中的标识符应位于主题备用名称扩展中,否则,应位于主题可分辨名称的通用名称 (CN) 中。

在这里,您的证书似乎只有一个 CN,并且该 CN 用于“9200416 arx sa cert”。

原则上,您可以通过使用开发机器上的hosts 文件将该名称指向您的本地主机来解决该问题。但是,该名称包含空格,因此它甚至不是有效的主机名。

你有几个选择:

  1. 为该应用程序重新生成证书,以便它使用正确的主机名(如果需要,修改您的 hosts 文件)。这可能只是设置时的错误。也许有人只是用空格填充了该名称,却没有意识到它会像在证书中那样使用(例如,OpenSSL 有时将其称为“您的名称”)。

  2. 一个不好的选择是更改您的应用程序以忽略主机名验证。这是一个糟糕的选择,因为这会使您的代码容易受到 MITM 攻击。当然,从 localhost 到 localhost 这几乎无关紧要,但这是保留在代码中的那种代码。因为它会防止错误(否则会是预期错误)的发生,所以很可能会忘记从生产代码中删除它。即使在具有良好开发实践的地方,也很容易错过。这是一个糟糕的选择(只是强调这一点)。

    对此稍好一点的变体是有一个自定义主机名验证器,它检查它找到的名称是您知道在证书中的名称。

【讨论】:

  • 非常感谢,我会尝试应用您的解决方案。尽管您说 2 号是一个糟糕的解决方案,但该程序只能在除我自己以外的任何人都无法访问的安全机器(或最多 3 台不同的机器)上运行,并且运行的服务器也是如此ARX 程序。覆盖 HostNameVerifier (stackoverflow.com/questions/6031258/…) 并在启动时添加 --javaagent 参数是否足以完成此任务?再次感谢您的回答!
猜你喜欢
  • 2018-06-18
  • 2016-08-09
  • 1970-01-01
  • 2016-12-27
  • 1970-01-01
  • 2015-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多