javax.net.ssl.SSLPeerUnverifiedException:<sub.app.domain> 的证书与任何主题替代名称都不匹配:[*.app.domain]]

Posted

技术标签:

【中文标题】javax.net.ssl.SSLPeerUnverifiedException:<sub.app.domain> 的证书与任何主题替代名称都不匹配:[*.app.domain]]【英文标题】:javax.net.ssl.SSLPeerUnverifiedException: Certificate for <sub.app.domain> doesn't match any of the subject alternative names: [*.app.domain]] 【发布时间】:2020-03-02 23:26:04 【问题描述】:

我正在使用自定义私有 CA,并希望在两个服务之间进行通信,这两个服务都使用自定义证书。但是,我收到一个我不明白的错误

因此,在这两种服务上,我都使用私有 CA 设置了一个信任库,并使用它标识自己的证书设置了一个单独的密钥库。在浏览器中转到一个简单的 /hello 路由表明连接是安全的(即发行者是已知的并且公用名是有效的)。当我curl -iv https://address 时也是如此,它表示握手通过说“SSL 证书验证正常”并且域与证书上的通配符名称匹配。

但是,当我尝试从以完全相同的方式设置的单独服务执行简单的 GET 请求时,我收到标题中列出的错误。问题是它说我尝试联系的服务的证书无法将其证书中的任何主题替代名称与其注册的域匹配。但这绝对是不正确的,唯一的区别是它使用了通配符。这适用于浏览器和调试握手的 curl 命令。它只是不是来自我在单独微服务上的 Java/Spring Boot 代码。

Java 是否以更严格的方式工作,这意味着它不喜欢使用通配符证书联系服务器?

编辑:添加下面显示的行修复了此问题,因此它在 Java 中的主机名验证失败(但在浏览器上或使用 curl 调试时失败)。这是不安全的,所以它不是解决方案。

SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(truststore, null).build();
HostnameVerifier hostnameVerifier = new NoopHostnameVerifier(); // I added this line, but it's advised against as it's insecure
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);

【问题讨论】:

可能是适当的:***.com/questions/7615645/… Java 对其 SSL 实现非常严格。如果您尝试连接的服务器没有正确且完全支持 SNI,则可能会导致此问题。 异常末尾的第二个方括号是错字吗?如果没有,则需要在证书上检查定义的 SAN :) 【参考方案1】:

所以我设法通过添加自己的 HostnameVerification 方法来解决这个问题。我以此为例https://raw.githubusercontent.com/masover/wildcard-hostname-verifier/master/src/net/forkbox/weblogic/WildcardHostnameVerifier.java

【讨论】:

这似乎只考虑了主题,而不考虑 SAN 扩展。 @PatrickMevzek 这对我来说很好。尽管错误以这种方式构成,但我没有任何 SAN 扩展。只是一个通用名称。 是的,但在许多情况下,例如 HTTPS,客户端不太关心/根本不关心 CN 中的内容,只关心 SAN。换句话说:您可能会遇到唯一有用部分位于 SAN 中的证书。如果事情现在对您有用,那就太好了,我的评论只是为了提醒未来的读者,以下代码遗漏了部分问题,并且基本上不遵循 RFC 6125 §6 尤其是 §6.4.4 中概述的算法:“作为最后的手段,客户端可以在主题字段的通用名称字段中检查其形式与完全限定的 DNS 域名匹配的字符串"

以上是关于javax.net.ssl.SSLPeerUnverifiedException:<sub.app.domain> 的证书与任何主题替代名称都不匹配:[*.app.domain]]的主要内容,如果未能解决你的问题,请参考以下文章