3

I am facing an exception while accessing https URLs through java code. When I try to access, I get the following exception:

Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching localhost found
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
        at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509)
        at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
        at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
        at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
        at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:81)
        at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
        at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
        at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:569)
        ... 131 more
Caused by: java.security.cert.CertificateException: No name matching localhost found
        at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:221)
        at sun.security.util.HostnameChecker.match(HostnameChecker.java:95)
        at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:455)
        at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:436)
        at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:200)
        at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491)

I tried to generate SSL certificate using the below command :

./jdk1.8/bin/keytool -genkey -keystore /srv/jakarta/.keystore -alias ALIAS \
    -keyalg RSA -keysize 4096 -validity 720
Enter keystore password: # well, enter something
Re-enter new password: # same as above
What is your first and last name?
  [Unknown]:  localhost # !!! IMPORTANT this is the domain name, NOT YOUR name
What is the name of your organizational unit?
  [Unknown]:  # enter something or leave empty
What is the name of your organization?
  [Unknown]:  # enter something or leave empty
What is the name of your City or Locality?
  [Unknown]:  # enter something or leave empty
What is the name of your State or Province?
  [Unknown]:  # enter something or leave empty
What is the two-letter country code for this unit?
  [Unknown]:  # enter something or leave empty
Is CN=example com, OU=Foo, O=Bar, L=City, ST=AA, C=FB correct?
  [no]:  yes
Enter key password for <lea-prod>
    (RETURN if same as keystore password): # Press RETURN

and with below tomcat/server.xml configuration :

 <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
       maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
       clientAuth="false" sslProtocol="TLS"
       keyAlias="ALIAS" keystoreFile="/srv/jakarta/.keystore"
       keystorePass="PW from step 1" />

However, its still not working and I am facing the same error.

Is there any way I can resolve this ? Thanks

AppleBud
  • 1,501
  • 8
  • 31
  • 47
  • Do you access the URL using localhost? If so, is your certificate name localhost? Have you then added the SSL certificate to as trusted? – StefanE Aug 01 '17 at 13:36
  • Yes, I can access the URLs directly on localhost and certificate name is localhost. I have created a local keystore rather than adding it to the windows keystore. does that make it trusted? I got little idea about that. – AppleBud Aug 01 '17 at 13:41
  • Assuming you are accessing the url from a Java program, you need then to add the cert as trusted into your keystore. https://docs.oracle.com/javase/tutorial/security/toolsign/rstep2.html – StefanE Aug 01 '17 at 13:52

2 Answers2

4

Well, it's exactly as the error message suggets. You certificate was issued on the common name example.com. However, you entered localhost as your server's name in your address bar. These two don't match, obviously. You should change your certificates common name (CN) to localhost as well, i.e. regenerate the certificate as you already did but with the correct name localhost.

In a next step you then need to import that certificate into your browser's certificate store. But this is another topic. The exception should be gone after you correct your certificate's common name.

Björn Zurmaar
  • 826
  • 1
  • 9
  • 22
  • That was my mistake @Bjorn Zurmaar. I have named it localhost only and added it to the locallly generated keystore than windows default keystore. But I am not accessing the URLs on browser. I am accessing those through code – AppleBud Aug 01 '17 at 13:44
  • How you access the URL (via Browser or by executing any other piece of code) doesn't play a role. If there is an SSL handshake the certificate's common name and the hostname have to match. If they don't the certificate _must_ be rejected. Otherwise you could have one valid certificate and place that on any server you like to make it seem legit. – Björn Zurmaar Aug 01 '17 at 14:03
0

I believe you are trying to access a service hosted on HTTPS protocol. In such case you will need to get the certificate of the website / service and add it to your java keystore. This is the way you should use certificates in production code

Alternatively you can override the HostNameVerifier class to suppress any errors and set it up in your java SSL context to ignore any errors. Ideally one would user suppression of check in testing code or when SSL certificates is unavailable.

Imtiyaz J
  • 19
  • 1
  • the website is on my local machine. there are few urls i want to access using https but still its giving me error : sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:455) – AppleBud Aug 01 '17 at 16:48
  • In that case try to over ride SSLContext and set up a dummy TrustStore [Sample](https://stackoverflow.com/questions/3674849/how-support-multiple-truststores-in-java-ssl-client-application) [Sample2](https://stackoverflow.com/questions/24555890/using-a-custom-truststore-in-java-as-well-as-the-default-one) – Imtiyaz J Aug 01 '17 at 17:13