SSLHandshakeException:证书中的主机名不匹配

时间:2013-10-10 09:49:17

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

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

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

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

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

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

1 个答案:

答案 0 :(得分:13)

证书本身似乎是可信的,因此您的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文件将该名称指向localhost来解决该问题。但是,该名称包含空格,因此它甚至不是有效的主机名。

你有几个选择:

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

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

    稍微好一点的变体是拥有一个自定义主机名验证程序,用于检查它找到的名称是否是您知道在证书中的名称。

相关问题