2

I'm using Spring WebClient to invoke a webservice over SSL, but I'm getting java.security.cert.CertificateException: No subject alternative DNS name matching lizzad.int.octa.com found.

As far as I can see, this means that the certificate does not have the name lizzad.int.octa.com. This makes some sense because I've the service invokation working if I invoke another url.

But I was told to change the URL and it was assured that the certificate should be the same. Nevertheless it is not working and then the client asked me if I could bypass something in order to make this work in tests environment.

After researching a bit I found some code I thought it could be hepful to configure 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();

But it seams that Matcher is not what will make the hostname to be ignore.

On the other hand I also found here [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;
            }
        });

that if I was not using WebClient I could set a HostnameVerifier and return true in order to bypass the hostname verification.

Do you know if it is possible and how can I define a HostnameVerifier like this in my WebClient Configuration to prevent java.security.cert.CertificateException: No subject alternative DNS name matching lizzad.int.octa.com

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

rui
  • 79
  • 2
  • 7

1 Answers1

0

I think this cannot be configured/ignored from the client side. You are trying to call the server on lizzad.int.octa.com and it is actually reaching it however the server is saying that it won't continue to talk with the client because lizzad.int.octa.com is not present within the SAN field of the server certificate.

This stackoverflow question/answer is similar to yours: Certificate for <localhost> doesn't match any of the subject alternative names

I would advise to recreate the server certificate if it is possible. You just need to add lizzad.int.octa.com as a DNS for the san field. See below for an example with 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
Hakan54
  • 3,121
  • 1
  • 23
  • 37
  • I had a clue that it was that the scenario, but the client insisted. Thanks a lot – rui Mar 21 '21 at 12:00