【问题标题】:java.security.cert.CertificateException: No subject alternative DNS name matching xxx foundjava.security.cert.CertificateException:找不到与 xxx 匹配的主题备用 DNS 名称
【发布时间】:2021-03-21 05:22:18
【问题描述】:

我正在使用 Spring WebClient 通过 SSL 调用 Web 服务,但我得到 java.security.cert.CertificateException: No subject Alternative DNS name matching lizzad.int.octa.com found .

据我所知,这意味着证书没有名称 lizzad.int.octa.com。这是有道理的,因为如果我调用另一个 url,我的服务调用就会工作。

但是我被告知要更改 URL,并确保证书应该是相同的。然而它不起作用,然后客户问我是否可以绕过某些东西以使其在测试环境中工作。

经过一番研究,我发现了一些我认为配置 WebClient 的代码。

TcpClient tcpClient = TcpClient.create().secure(sslContextSpec -> {
            // configure ssl
            SslContextBuilder sslContextBuilder = SslContextBuilder.forClient();
                sslContextBuilder
                        .trustManager(InsecureTrustManagerFactory.INSTANCE);
            
            sslContextSpec.sslContext(sslContextBuilder)
                    .defaultConfiguration(SslProvider.DefaultConfigurationType.NONE)
                    .handshakeTimeoutMillis(30)
                    .closeNotifyFlushTimeoutMillis(12000)
                    .closeNotifyReadTimeoutMillis(12000)
                    .handlerConfigurator(
                            (handler)->{
                                SSLEngine engine = handler.engine();
                                engine.setNeedClientAuth(true);
                                SSLParameters params = new SSLParameters();
                                List<SNIMatcher> matchers = new LinkedList<>();
                                SNIMatcher matcher = new SNIMatcher(0) {

                                    @Override
                                    public boolean matches(SNIServerName serverName) {
                                        return true;
                                    }
                                };
                                matchers.add(matcher);
                                params.setSNIMatchers(matchers);
                                engine.setSSLParameters(params);
                            }
                    )
            ;
        });
        HttpClient httpClient = HttpClient.from(tcpClient);

        return WebClient.builder()
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_OCTET_STREAM_VALUE)
                .clientConnector(new ReactorClientHttpConnector(httpClient)).build();

但很明显,Matcher 不会使主机名被忽略。

另一方面,我也在这里找到 [https://stackoverflow.com/questions/43371418/java-security-cert-certificateexception-no-subject-alternative-dns-name-matchin][1]

    new javax.net.ssl.HostnameVerifier() {

            public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) {
                    return true;
            }
        });

如果我不使用 WebClient,我可以设置一个 HostnameVerifier 并返回 true 以绕过主机名验证。

你知道这是否可能吗?如何在我的 WebClient 配置中定义这样的 HostnameVerifier 以防止 java.security.cert.CertificateException:没有与 lizzad.int.octa.com 匹配的主题备用 DNS 名称

谢谢 [1]:java.security.cert.CertificateException: No subject alternative DNS name matching

【问题讨论】:

    标签: ssl dns spring-webclient


    【解决方案1】:

    我认为这不能从客户端配置/忽略。您正在尝试在lizzad.int.octa.com 上调用服务器,它实际上正在到达它,但是服务器说它不会继续与客户端通信,因为lizzad.int.octa.com 不存在于服务器证书的 SAN 字段中。

    此 stackoverflow 问题/答案与您的类似:Certificate for <localhost> doesn't match any of the subject alternative names

    如果可能的话,我建议重新创建服务器证书。您只需添加 lizzad.int.octa.com 作为 san 字段的 DNS。请参阅下面的 keytool 示例:

    keytool -genkeypair -keyalg RSA -keysize 2048 -alias server -dname "CN=server,OU=some-organisation-unit,O=some-organisation,C=US" -ext "SAN:c=DNS:lizzad.int.octa.com,IP:127.0.0.1" -validity 3650 -keystore identity.jks -storepass secret -keypass secret -deststoretype pkcs12
    

    【讨论】:

    • 我知道是那个场景,但客户坚持。非常感谢
    猜你喜欢
    • 2019-05-17
    • 2019-09-23
    • 2015-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-02
    • 1970-01-01
    相关资源
    最近更新 更多