javax.net.ssl.SSLException: Certificate doesn't match any of the subject alternative names

前端 未结 5 849
攒了一身酷
攒了一身酷 2020-12-29 13:36

I recently added LetsEncrypt certificates to my server and my java applet is having problems connecting using TLS.

My applet uses Apache HttpClient.

My web s

相关标签:
5条回答
  • 2020-12-29 13:43

    I was getting the same error when I was using methods from org.apache.http.* for making my http requests. From your stack trace I assume that even you are using the same.

    This error disappeared when I used java.net.HttpURLConnection and I was able to connect successfully.

    import java.net.HttpURLConnection;
    
    public static HttpURLConnection connectToWeb(String uri) {
        HttpURLConnection connection = null;
        try {
            URL url = new URL(uri);
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();
        } catch (MalformedURLException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return connection;
    }
    
    0 讨论(0)
  • 2020-12-29 13:55

    Following Yurri's comment, it solved my problem by adding NoopHostnameVerifier.INSTANCE while initialising SSLConnectionSocketFactory :

    import org.apache.http.HttpHost;
    import org.apache.http.conn.ssl.NoopHostnameVerifier;
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClientBuilder;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.ssl.TrustStrategy;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.http.HttpEntity;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.HttpMethod;
    import org.springframework.http.MediaType;
    import org.springframework.http.ResponseEntity;
    import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
    import org.springframework.stereotype.Component;
    import org.springframework.web.client.HttpClientErrorException;
    import org.springframework.web.client.RestTemplate;
    
    import java.net.Proxy;
    import java.nio.charset.StandardCharsets;
    import java.security.KeyManagementException;
    import java.security.KeyStoreException;
    import java.security.NoSuchAlgorithmException;
    
    import javax.net.ssl.SSLContext;
    
    /**
     * Provide basic Utils for getting HttpHeader and making REST api calls.
     * 
     */
    @Component
    public class HttpUtil {
    
        private static final Logger LOG = LoggerFactory.getLogger(HttpUtil.class);
    
        /**
         * The default implementation to get basic headers.
         * @return HttpHeaders.
         */
        public HttpHeaders getHttpHeaders(String userAgent, String host) {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set(HttpHeaders.ACCEPT_CHARSET, StandardCharsets.UTF_8.name());
            headers.set(HttpHeaders.USER_AGENT, userAgent);
            LOG.info("host=" + host);
            if (null != host) {
                headers.set(HttpHeaders.HOST, host);
            }
    
            return headers;
        }
    
        /**
         * Default implementation to get RestTemplate
         * @return
         */
         public RestTemplate getRestTemplate(String proxyHost, int proxyPort)
            throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
    
        TrustStrategy acceptingTrustStrategy = new TrustSelfSignedStrategy();
    
        SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy)
                .build();
    
        SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
    
        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).build();
    
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        if (null != proxyHost && proxyPort > 0) {
            LOG.info("PROXY CONFIGURED | proxyHost=" + proxyHost + " | proxyPort=" + proxyPort);
            HttpHost proxy = new HttpHost(proxyHost, proxyPort, Proxy.Type.HTTP.name());
            httpClient = HttpClients.custom().setSSLSocketFactory(csf)
                    .setRoutePlanner(new DefaultProxyRoutePlanner(proxy)).build();
        }
        requestFactory.setHttpClient(httpClient);
        RestTemplate restTemplate = new RestTemplate(requestFactory);
        return restTemplate;
    }
    
        /**
         * Make a rest api call
         * @return ResponseEntity
         */
        public ResponseEntity<String> getApiResponse(HttpMethod httpMethod, final String URL, final String userAgent,
                String proxyHost, int proxyPort, String host) throws HttpClientErrorException {
            ResponseEntity<String> response = null;
            HttpEntity<String> httpEntity = new HttpEntity<>(getHttpHeaders(userAgent, host));
            try {
                if (null != httpMethod && null != URL) {
                    RestTemplate request = null;
                    try {
                        request = getRestTemplate(proxyHost, proxyPort);
                        response = request.exchange(URL, httpMethod, httpEntity, String.class);
                    } catch (KeyManagementException | KeyStoreException | NoSuchAlgorithmException e) {
                        LOG.error("Error creating Rest Template", e);
                    }
                }
            } catch (HttpClientErrorException ex) {
                LOG.error("Method = " + httpMethod.toString() + "Request URL = " + URL);
                LOG.error("Headers =" + getHttpHeaders(userAgent, host));
                LOG.error("Response Status = " + ex.getStatusText());
                LOG.error("Response Body = " + ex.getResponseBodyAsString());
                throw ex;
            }
            return response;
        }
    }

    0 讨论(0)
  • 2020-12-29 14:00

    I don't know which version of the Apache HttpClient you were using but versions 4.4.1 and 4.5.1 had a bug where the SNI didn't work correctly. This was fixed in 4.5.3

    https://issues.apache.org/jira/browse/HTTPCLIENT-1726

    0 讨论(0)
  • 2020-12-29 14:09

    If you use HttpClient 4.4 then you need to specify host verifier (NoopHostnameVerifier) to allow accepting certificates from different hosts:

    SSLConnectionSocketFactory scsf = SSLConnectionSocketFactory(
         SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build(), 
            NoopHostnameVerifier.INSTANCE)
    httpclient = HttpClients.custom().setSSLSocketFactory(scsf).build()
    
    0 讨论(0)
  • 2020-12-29 14:09
    /*
     * Inner class for Proxy SSL Socket Connection.
     */
    static class MyConnectionSocketFactory extends SSLConnectionSocketFactory {
        private String proxyHost = null;
        private Integer proxyPort = null;
    
        public MyConnectionSocketFactory(final SSLContext sslContext, String proxyHost, Integer proxyPort) {
            super(sslContext, new NoopHostnameVerifier());
            this.proxyHost = proxyHost;
            this.proxyPort = proxyPort;
        }
    
        @Override
        public Socket createSocket(final HttpContext context) throws IOException {
            logger.debug("Create Socket:" + " ProxyHost: " + proxyHost + ", ProxyPort: " + proxyPort);
            InetSocketAddress socksaddr = new InetSocketAddress(proxyHost,proxyPort);
            Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksaddr);
            return new Socket(proxy);
        }
    }
    
    
       else if (proxyType.equalsIgnoreCase("socks")) {
            logger.debug("Proxy Type: " + proxyType);
            TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                    return true;
                }
            };
    
            SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()
                    .loadTrustMaterial(null, acceptingTrustStrategy)
                    .build();
            SSLConnectionSocketFactory csf = new MyConnectionSocketFactory(sslContext, proxyHost, proxyPort);
            CloseableHttpClient httpClient = HttpClients.custom()
                    .setSSLSocketFactory(csf)
                    .build();
            HttpComponentsClientHttpRequestFactory requestFactory =
                    new HttpComponentsClientHttpRequestFactory();
            requestFactory.setHttpClient(httpClient);
            restTemplate = new RestTemplate(requestFactory);
            return;
        } else {
    
    0 讨论(0)
提交回复
热议问题