简体   繁体   English

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

[英]Java: Overriding function to disable SSL certificate check

The web service is rest over SSL and it has self signed certificate, hosted in remote system.I have already created a client accessing that web service. Web服务通过SSL进行,它具有自签名证书,托管在远程系统中。我已经创建了一个访问该Web服务的客户端。 This is done by adding the certificate to the key store programatically . 这是通过以编程方式将证书添加到密钥库来完成的。

Now I heard that, it is not necessary to add certificate to key store for accesing a self signed web service. 现在我听说,没有必要将证书添加到密钥库以访问自签名Web服务。 Instead we can disable the certificate check by overriding some methods. 相反,我们可以通过覆盖某些方法来禁用证书检查。 Is this true? 这是真的? Which are those methods? 那些方法是哪些? Please help. 请帮忙。

This should be sufficient. 这应该足够了。 I use this when testing code against testing and staging servers where we don't have properly signed certificates. 我在测试代码时测试和暂存我们没有正确签名证书的服务器时使用它。 However, you should really really strongly consider getting a valid SSL certificate on your production server . 但是,您应该非常强烈地考虑在生产服务器上获取有效的SSL证书 Nobody wants to be wiretapped and have their privacy violated. 没有人想要被窃听,并且他们的隐私受到侵犯。

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;
    }
});

And this. 还有这个。

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) {
    }

}

Best of luck! 祝你好运!

===UPDATE=== === UPDATE ===

I just wanted to point out that there's a service called Let's Encrypt which automates the process of generating and setting up SSL/TLS certificates recognised by virtually everybody, and it's absolutely free! 我只是想指出,有一个名为Let's Encrypt的服务可以自动生成和设置几乎所有人都能识别的SSL / TLS证书的过程,而且它是完全免费的!

Ignoring certs on a per-connection basis is much safer since any other code will still use the secure defaults. 由于任何其他代码仍将使用安全默认值,因此在每个连接的基础上忽略证书会更安全。

The following code: 以下代码:

  • Overrides the trust manager and hostname verifier on a per-connection basis. 基于每个连接覆盖信任管理器和主机名验证程序。
  • Reuses the SSLSocketFactory in order to support persistent connections, bypassing the expensive SSL handshake for repeated requests to the same server. 重用SSLSocketFactory以支持持久连接,绕过昂贵的SSL握手以重复请求到同一服务器。

As others have stated, this should only be used for testing, and/or for internal systems communicating with other internal systems. 正如其他人所说,这应仅用于测试,和/或用于与其他内部系统通信的内部系统。

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;
        }
    };

}

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

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();
        }               
}

I think it will working fine.because it fine of me... 我认为它会正常工作。因为我很好......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM