SSLHandshakeException:证书中的主机名不匹配
我正在编写一个系统,必须将一个多部分发布到服务器(一个名为ARX的第三方程序,当前在开发期间在localhost上运行),该服务器具有自签名证书。
我试图找到它的证书,但只能找到三个不同的jks文件; server.jks , servertrust.jks和serverca.jks 。
我试图使用每个jks文件的System.setProperty("javax.net.ssl.trustStore", "Program Files\\\\jksfile")
。 然而; 当我这样做时,我收到以下错误: 证书中的主机名不匹配:!= 。
我已经在stackoverflow上浏览了大量类似的问题,试图了解如何解决这个问题,但我无法解决我的问题。
有什么建议么? 非常感谢所有帮助。
证书本身似乎是可信的,因此您的javax.net.ssl.trustStore
设置有效,但主机名不匹配。
根据客户端如何识别它尝试访问的主机来完成主机名匹配。 如果它尝试访问https://localhost/
,则证书必须对localhost
有效。 如果它正在尝试访问https://something-else.example
,那么证书必须对something-else.example
有效something-else.example
,即使localhost
和something-else.example
是同一台机器也是如此。
证书中的标识符应该在主题备用名称扩展名中,或者在主题可分辨名称的公用名(CN)中失败。
在这里,看起来你的证书只有CN,而且这个CN用于“ 9200416 arx sa cert
”。
原则上,您可以通过使用开发计算机上的hosts
文件将该名称指向localhost来解决该问题。 但是,该名称包含空格,因此它甚至不是有效的主机名。
你有几个选择:
-
为该应用程序重新生成证书,以便它使用正确的主机名(如果需要,还可以调整
hosts
文件)。 这可能只是在设置时出错。 也许有人只是用空格填充了这个名字,却没有意识到它会像证书那样被使用(例如,OpenSSL有时称之为“你的名字”)。 -
一个糟糕的选择是更改您的应用程序以忽略主机名validation。 这是一个糟糕的选择,因为这会使您的代码对MITM攻击开放。 当然,这从localhost到localhost几乎不重要,但这就是代码中保留的代码。 因为它可以防止发生错误(否则会出现预期的错误),所以很可能会忘记从生产代码中删除它。 即使在具有良好开发实践的地方,也很容易错过。 这是一个糟糕的选择(只是为了强调这一点)。
稍微好一点的变体是拥有一个自定义主机名validation程序,用于检查它找到的名称是否是您知道在证书中的名称。
- 在客户端接收多部分响应(ClosableHttpResponse)
- Apache PoolingHttpClientConnectionManager抛出非法状态exception
- Java http客户端和POODLE
- 在Spring 3.1中使用Basic Auth进行RestTemplate
- 要传递给Java应用程序以使用http代理进行身份validation的Java属性
- 使用apache httpClient客户端将发布数据发送到https而不使用ssl证书validation
- Apache HTTPClient SSLPeerUnverifiedException
- 尝试进行客户端服务器ssl身份validation时,Tomcat 7获取SSLv2Hello被禁用错误
- 连接和连接请求超时