首页 文章

Java:覆盖禁用SSL证书检查的功能

提问于
浏览
26

Web服务通过SSL进行,它具有自签名证书,托管在远程系统中 . 我已经创建了一个访问该Web服务的客户端 . 这是通过将证书添加到key store programatically来完成的 .

现在我听说,没有必要将证书添加到密钥库以访问自签名Web服务 . Instead we can disable the certificate check by overriding some methods. Is this true? Which are those methods? 请帮忙 .

3 回答

  • 11

    这应该足够了 . 我在测试代码时测试和暂存我们没有正确签名证书的服务器时使用它 . However, you should really really strongly consider getting a valid SSL certificate on your production server . 没有人想要被窃听,并且他们的隐私受到侵犯 .

    SSLContext sc = SSLContext.getInstance("TLS");
    sc.init(null, new TrustManager[] { new TrustAllX509TrustManager() }, new java.security.SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    HttpsURLConnection.setDefaultHostnameVerifier( new HostnameVerifier(){
        public boolean verify(String string,SSLSession ssls) {
            return true;
        }
    });
    

    还有这个 .

    import javax.net.ssl.X509TrustManager;
    import java.security.cert.X509Certificate;
    
    /**
     * DO NOT USE IN PRODUCTION!!!!
     * 
     * This class will simply trust everything that comes along.
     * 
     * @author frank
     *
     */
    public class TrustAllX509TrustManager implements X509TrustManager {
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    
        public void checkClientTrusted(java.security.cert.X509Certificate[] certs,
                String authType) {
        }
    
        public void checkServerTrusted(java.security.cert.X509Certificate[] certs,
                String authType) {
        }
    
    }
    

    祝你好运!

    ===UPDATE===

    我只是想指出,有一个名为Let's Encrypt的服务可以自动生成和设置几乎所有人都能识别的SSL / TLS证书的过程,而且它是完全免费的!

  • 0

    由于任何其他代码仍将使用安全默认值,因此在每个连接的基础上忽略证书会更安全 .

    以下代码:

    • 基于每个连接覆盖信任管理器和主机名验证程序 .

    • 重用SSLSocketFactory以支持持久连接,绕过对同一服务器的重复请求进行昂贵的SSL握手 .

    正如其他人所说,这应仅用于测试,和/或用于与其他内部系统通信的内部系统 .

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.security.KeyManagementException;
    import java.security.NoSuchAlgorithmException;
    import java.security.cert.X509Certificate;
    
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.HttpsURLConnection;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSession;
    import javax.net.ssl.SSLSocketFactory;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    
    public class TestPersistentConnection
    {
        private static SSLSocketFactory sslSocketFactory = null;
    
        /**
         * Use the VM argument <code>-Djavax.net.debug=ssl</code> for SSL specific debugging;
         * the SSL handshake will appear a single time when connections are re-used, and multiple
         * times when they are not.
         * 
         * Use the VM <code>-Djavax.net.debug=all</code> for all network related debugging, but 
         * note that it is verbose.
         * 
         * @throws Exception
         */
        public static void main(String[] args) throws Exception
        {
    
            //URL url = new URL("https://google.com/");
            URL url = new URL("https://localhost:8443/");
    
            // Disable first
            request(url, false);
    
            // Enable; verifies our previous disable isn't still in effect.
            request(url, true);
        }
    
        public static void request(URL url, boolean enableCertCheck) throws Exception {
            BufferedReader reader = null;
            // Repeat several times to check persistence.
            System.out.println("Cert checking=["+(enableCertCheck?"enabled":"disabled")+"]");
            for (int i = 0; i < 5; ++i) {
                try {
    
                    HttpURLConnection httpConnection = (HttpsURLConnection) url.openConnection();
    
                    // Normally, instanceof would also be used to check the type.
                    if( ! enableCertCheck ) {
                        setAcceptAllVerifier((HttpsURLConnection)httpConnection);
                    }
    
                    reader = new BufferedReader(new InputStreamReader(httpConnection.getInputStream()), 1);
    
                    char[] buf = new char[1024];
                    StringBuilder sb = new StringBuilder();
                    int count = 0;
                    while( -1 < (count = reader.read(buf)) ) {
                        sb.append(buf, 0, count);
                    }
                    System.out.println(sb.toString());
    
                    reader.close();
    
                } catch (IOException ex) {
                    System.out.println(ex);
    
                    if( null != reader ) {
                        reader.close();
                    }
                }
            }
        }
    
        /**
         * Overrides the SSL TrustManager and HostnameVerifier to allow
         * all certs and hostnames.
         * WARNING: This should only be used for testing, or in a "safe" (i.e. firewalled)
         * environment.
         * 
         * @throws NoSuchAlgorithmException
         * @throws KeyManagementException
         */
        protected static void setAcceptAllVerifier(HttpsURLConnection connection) throws NoSuchAlgorithmException, KeyManagementException {
    
            // Create the socket factory.
            // Reusing the same socket factory allows sockets to be
            // reused, supporting persistent connections.
            if( null == sslSocketFactory) {
                SSLContext sc = SSLContext.getInstance("SSL");
                sc.init(null, ALL_TRUSTING_TRUST_MANAGER, new java.security.SecureRandom());
                sslSocketFactory = sc.getSocketFactory();
            }
    
            connection.setSSLSocketFactory(sslSocketFactory);
    
            // Since we may be using a cert with a different name, we need to ignore
            // the hostname as well.
            connection.setHostnameVerifier(ALL_TRUSTING_HOSTNAME_VERIFIER);
        }
    
        private static final TrustManager[] ALL_TRUSTING_TRUST_MANAGER = new TrustManager[] {
            new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                public void checkClientTrusted(X509Certificate[] certs, String authType) {}
                public void checkServerTrusted(X509Certificate[] certs, String authType) {}
            }
        };
    
        private static final HostnameVerifier ALL_TRUSTING_HOSTNAME_VERIFIER  = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };
    
    }
    

    非常感谢:http://runtime32.blogspot.com/2008/11/let-java-ssl-trust-all-certificates.html

  • 33
    TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return null;
                        }
                        public void checkClientTrusted(X509Certificate[] certs, String authType) {
                        }
                        public void checkServerTrusted(X509Certificate[] certs, String authType) {
                        }
                    }
                };
                SSLContext sc = SSLContext.getInstance("SSL");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    
                HostnameVerifier allHostsValid = new HostnameVerifier() {
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                };
                HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
                GetCustomerPhone http = new GetCustomerPhone(); 
    
        System.out.println("Processing..");     
         try{
                http.sendPost();    
            }
        catch(Exception e){
                e.printStackTrace();
            }               
    }
    

    我认为它会正常工作 . 因为我很好......

相关问题