Accept server's self-signed ssl certificate in Java client

后端 未结 12 1660
日久生厌
日久生厌 2020-11-22 00:04

It looks like a standard question, but I couldn\'t find clear directions anywhere.

I have java code trying to connect to a server with probably self-signed (or expir

12条回答
  •  长情又很酷
    2020-11-22 00:43

    I had the issue that I was passing a URL into a library which was calling url.openConnection(); I adapted jon-daniel's answer,

    public class TrustHostUrlStreamHandler extends URLStreamHandler {
    
        private static final Logger LOG = LoggerFactory.getLogger(TrustHostUrlStreamHandler.class);
    
        @Override
        protected URLConnection openConnection(final URL url) throws IOException {
    
            final URLConnection urlConnection = new URL(url.getProtocol(), url.getHost(), url.getPort(), url.getFile()).openConnection();
    
            // adapated from
            // https://stackoverflow.com/questions/2893819/accept-servers-self-signed-ssl-certificate-in-java-client
            if (urlConnection instanceof HttpsURLConnection) {
                final HttpsURLConnection conHttps = (HttpsURLConnection) urlConnection;
    
                try {
                    // Set up a Trust all manager
                    final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
    
                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return null;
                        }
    
                        @Override
                        public void checkClientTrusted(final java.security.cert.X509Certificate[] certs, final String authType) {
                        }
    
                        @Override
                        public void checkServerTrusted(final java.security.cert.X509Certificate[] certs, final String authType) {
                        }
                    } };
    
                    // Get a new SSL context
                    final SSLContext sc = SSLContext.getInstance("TLSv1.2");
                    sc.init(null, trustAllCerts, new java.security.SecureRandom());
                    // Set our connection to use this SSL context, with the "Trust all" manager in place.
                    conHttps.setSSLSocketFactory(sc.getSocketFactory());
                    // Also force it to trust all hosts
                    final HostnameVerifier allHostsValid = new HostnameVerifier() {
                        @Override
                        public boolean verify(final String hostname, final SSLSession session) {
                            return true;
                        }
                    };
    
                    // and set the hostname verifier.
                    conHttps.setHostnameVerifier(allHostsValid);
    
                } catch (final NoSuchAlgorithmException e) {
                    LOG.warn("Failed to override URLConnection.", e);
                } catch (final KeyManagementException e) {
                    LOG.warn("Failed to override URLConnection.", e);
                }
    
            } else {
                LOG.warn("Failed to override URLConnection. Incorrect type: {}", urlConnection.getClass().getName());
            }
    
            return urlConnection;
        }
    
    }
    

    Using this class it is possible to create a new URL with:

    trustedUrl = new URL(new URL(originalUrl), "", new TrustHostUrlStreamHandler());
    trustedUrl.openConnection();
    

    This has the advantage that it is localized and not replacing the default URL.openConnection.

提交回复
热议问题