java.security.cert.CertificateException: No name matching localhost found

Problem

Configured Tomcat to support SSL and deployed this simple hello world web service. And use following client connect to the deployed web service over SSL connection :


package com.mkyong.client;

import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

import com.mkyong.ws.HelloWorld;

public class HelloWorldClient{
	
	public static void main(String[] args) throws Exception {
	   
	URL url = new URL("https://localhost:8443/HelloWorld/hello?wsdl");
        QName qname = new QName("http://ws.mkyong.com/", "HelloWorldImplService");

        Service service = Service.create(url, qname);
        HelloWorld hello = service.getPort(HelloWorld.class);
        System.out.println(hello.getHelloWorldAsString());
       
    }
}

It hits “No name matching localhost found” exception :


Caused by: javax.net.ssl.SSLHandshakeException: 
    java.security.cert.CertificateException: No name matching localhost found
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1611)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:187)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:181)
	......
Caused by: java.security.cert.CertificateException: No name matching localhost found
	at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:210)
	at sun.security.util.HostnameChecker.match(HostnameChecker.java:77)
	......

Solution

This problem and solution is well explained in this article, you can use a Transport Security (SSL) Workaround for your “localhost” development environment.

To fix it, add a javax.net.ssl.HostnameVerifier() method to override the existing hostname verifier like this :


package com.mkyong.client;

import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

import com.mkyong.ws.HelloWorld;

public class HelloWorldClient{
	
	static {
	    //for localhost testing only
	    javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
	    new javax.net.ssl.HostnameVerifier(){

	        public boolean verify(String hostname,
	                javax.net.ssl.SSLSession sslSession) {
	            if (hostname.equals("localhost")) {
	                return true;
	            }
	            return false;
	        }
	    });
	}
	
	public static void main(String[] args) throws Exception {
	   
	URL url = new URL("https://localhost:8443/HelloWorld/hello?wsdl");
        QName qname = new QName("http://ws.mkyong.com/", "HelloWorldImplService");

        Service service = Service.create(url, qname);
        HelloWorld hello = service.getPort(HelloWorld.class);
        System.out.println(hello.getHelloWorldAsString());
       
    }
}

Output


Hello World JAX-WS

It’s working fine now.

29 comments on “java.security.cert.CertificateException: No name matching localhost found

  1. javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
            (hostname, sslSession) -> hostname.equals("localhost"));
    

    java8 synthax

    Reply
  2. the referenced article on oracle.com cannot be found

    Reply
  3. hello i am using the above code to call a solr api but its giving the exception “sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target” can you tell me what should i do

    Reply
      1. descargar el certificado, Firefox options>Advanced>Certificates>View Certificates>Add exception> url>view>Details>Export guardar como .cer
        despues desde cmd abrir cd %java_home%, cd bin ya en bin usar el keytool, e.g.:
        C:Program Files (x86)Javajdk1.8.0_111bin>keytool -import -alias xstore -keystore “C:Program Files (x86)Javajdk1.8.0_111jrelibsecuritycacerts” -file C:xauthcertificatexstore.cer

        Ahi se agrega el certificado al cacerts y listo, para ver los certificados para asegurar que se haya agregado se puede utilizar el comando
        keytool -list -v -keystore “C:Program Files (x86)Javajdk1.8.0_111jrelibsecuritycacerts” > java_cacerts.txt

        Reply
  4. Thank you for the explanation!
    The link to the related Oracle article is broken.

    Reply
  5. Thank you, mkyong. Your articles very useful for me)

    Reply
  6. Hi, Thank you very much! Just what I needed 🙂

    Reply
  7. Hey Thanks alot, I’m using JAVA FX WebEngine to load the URL, and used your static block to by pass the SSL issue.

    Reply
  8. I was on this for nearly a week, and finally the method solved it. Can you please provide an updated link to the article that explains the solution in more detail or if you can explain what the method is doing it would be highly useful.

    Reply
  9. Excellent post as always! Thank you very much!

    Reply
  10. Your tutorials are the simplest, the best, the easiest to implement and understand and last but not the least THE AWESOMEST!!!

    Reply
  11. Great article, I wish I would start the search here :). My problem was that I tried to load a JavaFX WebEngine to ‘https://localhost/…’ and may server had a self-signed certificate. Adding the static part in the Controller class fixed my problem.

    Thank you.

    Reply
  12. hello,

    I configure a HTTPS webservice adding below constraings to the web.xml:

     
    <security-constraint>
            <web-resource-collection>
                <web-resource-name>Secure Area</web-resource-name>
                <url-pattern>/*
                </url-pattern>
                <http-method>POST</http-method>
            </web-resource-collection>
            <auth-constraint>
                <role-name>EMPLOYEE</role-name>
            </auth-constraint>
            <user-data-constraint>
                <transport-guarantee>CONFIDENTIAL</transport-guarantee>
            </user-data-constraint>
        </security-constraint>
    

    when I create a testClient and run it, Netbeans say me:
    Exception in thread “main” javax.xml.ws.WebServiceException: Cannot find ‘https://localhost:8181/Webservice/Service?wsdl’ wsdl. Place the resource correctly in the classpath.

    What could I do?
    Thanks in advance

    Reply
    1. hi.. did you manage to get around with this problem?

      I’m facing the same issue..

      Reply
      1. Hi.. If you want to make it work in your local environment but can’t create a class like the one proposed above, let’s say you’re executing wsimport using maven, you can just create a self signed certificate and add it to your JDK’s truststore (i.e. cacerts)

        For example if you’re using unix:

        1. create a self signed certificate (with validity of 1 year, increase it if you like; change the name of -keystore parameter to your own tomcat’s keystore)
        > keytool -genkey -alias localhost -keyalg RSA -validity 365 -keypass changeit -keystore your-keystore.jks -storepass changeit -dname “CN=localhost, OU=anyOrgUnit, O=anyOrg, C=US, ST=anyState, L=anyCity”

        Note: CN must be localhost

        2. export certificate
        > keytool -exportcert -rfc -alias localhost -file localhost.cer -keystore your-keystore.jks -storepass changeit

        3. locate your cacerts, mine is in /etc/ssl/certs/java

        4. import your self signed cert to cacerts
        > sudo keytool -noprompt -importcert -alias localhost -file localhost.cer -keystore cacerts -storepass changeit

        Note: I’m assuming you will be copying the localhost.cer to /etc/ssl/certs/java to make the parameter in -file short but if not then specify the absolute path to your own localhost.cer

        5. verify that the cert was added to your truststore
        > keytool -list -keystore cacerts | grep localhost

        Note: it should show 1 entry

        Reply
        1. This solution is NOT useful. I have applied and I getting the same error.

          Before publish a solution it SHOULD BE tested.

          Reply
  13. i ma getting

    java.net.UnknownServiceException: no content-type
    at java.net.URLConnection.getContentHandler(URLConnection.java:1209)
    at java.net.URLConnection.getContent(URLConnection.java:706)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getContent(HttpsURLConnectionImpl.java:426)
    at MutualAuthenticationHTTP.doitAll(MutualAuthenticationHTTP.java:100)
    at MutualAuthenticationHTTP.main(MutualAuthenticationHTTP.java:75)

    pl help

    Reply

Leave a Comment

Your email address will not be published. Required fields are marked *