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.
Thank you for the explanation!
The link to the related Oracle article is broken.
https://docs.oracle.com/cd/E19159-01/820-1072/6ncp48v40/index.html
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
I have been facing the same. Please help.
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
java8 synthax
Thank you sir. Really helpful for the code.
the referenced article on oracle.com cannot be found
Thank you, mkyong. Your articles very useful for me)
thanks – works fine 🙂
Thanx, excellent solution !!
awesome fix …
Hi, Thank you very much! Just what I needed 🙂
Hey Thanks alot, I’m using JAVA FX WebEngine to load the URL, and used your static block to by pass the SSL issue.
I had this problem, thank you for the solutiion.
many thanks …
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.
Excellent post as always! Thank you very much!
Your tutorials are the simplest, the best, the easiest to implement and understand and last but not the least THE AWESOMEST!!!
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.
awesome, didn’t know about that. thanks!
hi bro,,
thank you
your answer perfect…
Thanks!! very useful
hello,
I configure a HTTPS webservice adding below constraings to the web.xml:
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
hi.. did you manage to get around with this problem?
I’m facing the same issue..
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
This solution is NOT useful. I have applied and I getting the same error.
Before publish a solution it SHOULD BE tested.
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
Hello, Thank you for posting this information. The article like appears to be broken or obsolete. This document http://docs.oracle.com/cd/E19159-01/820-1072/820-1072.pdf explains it on page 75 and may be what was originally pointed to.