3

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

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

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

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

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

4

1 回答 1

15

证书本身似乎受信任,因此您的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 这几乎无关紧要,但这是保留在代码中的那种代码。因为它会防止错误(否则会是预期错误)的发生,所以很可能会忘记从生产代码中删除它。即使在具有良好开发实践的地方,也很容易错过。这是一个糟糕的选择(只是强调这一点)。

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

于 2013-10-10T11:22:06.627 回答