0

I use SSL security in my Spring Boot application. While calling the address

final UriComponents uriComponents
            = uriComponentsBuilder.path("/api/v1.0/register/token/{token}").buildAndExpand(token);

    ResponseEntity<Boolean> response;

    try {
        response = restTemplate
                .exchange(uriComponents.toUri(),
                          HttpMethod.PUT,
                          entity,
                          Boolean.class);

throw away me https://pastebin.com/A4Vb69hT carefully

I/O error on PUT request for "https://localhost:8443/api/v1.0/register/token/PBe3AzJ245W0sNyeg": java.security.cert.CertificateException: No name matching localhost found; nested exception is javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching localhost found

I found on the Internet on the website http://java.globinch.com/enterprise-java/security/fix-java-security-certificate-exception-no-matching-localhost-found/

    static {
    //for localhost testing only
    javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
            (hostname, sslSession) -> hostname.equals("localhost"));
    }

after adding it, it receives further errors https://pastebin.com/kJZCqJ6K carefully

I/O error on PUT request for "https://localhost:8443/api/v1.0/register/token/EMNy7W9jJgsMWEn0z6hFOIHoB96zzSaeHWUs": sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; nested exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

What should I do now?

I have two SSL files https://github.com/JonkiPro/REST-Web-Services/tree/master/src/main/resources/keystore

sdfsd
  • 1,027
  • 2
  • 10
  • 15
  • As you want to use `HttpURLConnection` you have to define a SSLContext first. See [this question](https://stackoverflow.com/questions/30121510/java-httpsurlconnection-and-tls-1-2) on how to do it – Roman Vottner Oct 01 '17 at 02:11

3 Answers3

3

This answer is some kind of hack to run locally though enabling in actual environment will still work with certificates.

Just call SSLContextHelper.disable() before restTemplate.exchange

import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import javax.security.cert.X509Certificate;

import org.apache.log4j.Logger;

public class SSLContextHelper {

    private static final String KEY_STORE_TYPE="JKS";
    private static final String CLASS_NAME=SSLContextHelper.class.getName();
    private static final String TRANSPORT_SECURITY_PROTOCOL="TLS";
    private static final Logger logger=Logger.getLogger(SSLContextHelper.class);

    public static void enable(){
        String keystoreType = "JKS";
        InputStream keystoreLocation = null;
        char [] keystorePassword = null;
        char [] keyPassword = null;


        try {
              KeyStore keystore = KeyStore.getInstance(keystoreType);       
              keystore.load(keystoreLocation, keystorePassword);
              KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
              kmfactory.init(keystore, keyPassword);
              InputStream truststoreLocation = null;
              char [] truststorePassword = null;
              String truststoreType = KEY_STORE_TYPE;

              KeyStore truststore = KeyStore.getInstance(truststoreType);
              truststore.load(truststoreLocation, truststorePassword);
              TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

              KeyManager [] keymanagers = kmfactory.getKeyManagers();
            TrustManager [] trustmanagers =  tmfactory.getTrustManagers();

            SSLContext sslContext = SSLContext.getInstance(TRANSPORT_SECURITY_PROTOCOL);
            sslContext.init(keymanagers, trustmanagers, new SecureRandom());
            SSLContext.setDefault(sslContext);
        } catch (Exception e) {
            logger.error(CLASS_NAME+"Exception in SSL "+e.getMessage());
            e.printStackTrace();
        }
    }

    public static void disable() {
        try {
            SSLContext sslc = SSLContext.getInstance("TLS");
            TrustManager[] trustManagerArray = { (TrustManager) new NullX509TrustManager() };
            sslc.init(null, trustManagerArray, null);
            HttpsURLConnection.setDefaultSSLSocketFactory(sslc.getSocketFactory());
            HttpsURLConnection.setDefaultHostnameVerifier(new NullHostnameVerifier());
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    private static class NullX509TrustManager implements X509TrustManager {
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            System.out.println();
        }
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            System.out.println();
        }

    }

    private static class NullHostnameVerifier implements HostnameVerifier {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }
Barath
  • 5,093
  • 1
  • 17
  • 42
1

The certificate of server is not a valid certificate chain or is probably self signed. Add the certificate to your trust store as trusted certificate ( do it only if you know it's a testing local certificate) and then try.

For details you can see https://eclipse-ee4j.github.io/mail/InstallCert

Optional
  • 4,387
  • 4
  • 27
  • 45
0

Certificate does not match the hostname, in this case localhost. please check that your self-signed certificate is using the right CN and if not recreate it.

Good article how to fix error :

http://java.globinch.com/enterprise-java/security/fix-java-security-certificate-exception-no-matching-localhost-found/

vaquar khan
  • 10,864
  • 5
  • 72
  • 96