30

Web サービスは SSL 経由であり、リモート システムでホストされている自己署名証明書があります。その Web サービスにアクセスするクライアントを既に作成しています。これは、証明書を プログラムでキー ストアに追加することによって行われます。

自己署名 Web サービスにアクセスするために、キー ストアに証明書を追加する必要はないと聞きました。代わりに、いくつかのメソッドをオーバーライドして証明書チェックを無効にすることができます。これは本当ですか?それらの方法はどれですか?助けてください。

4

3 に答える 3

39

これで十分です。これは、適切に署名された証明書がないテスト サーバーおよびステージング サーバーに対してコードをテストするときに使用します。ただし、本番サーバーで有効な SSL 証明書を取得することを強く検討する必要があります。盗聴されてプライバシーが侵害されることは誰も望んでいません。

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

}

頑張ってください!

===更新===

Let's Encryptと呼ばれるサービスがあり、事実上すべての人が認識している SSL/TLS 証明書の生成と設定のプロセスを自動化します。これは完全に無料です。

于 2013-11-01T09:03:44.503 に答える
13

接続ごとに証明書を無視すると、他のコードは安全なデフォルトを引き続き使用するため、はるかに安全です。

次のコード:

  • 接続ごとにトラスト マネージャーとホスト名ベリファイアをオーバーライドします。
  • 永続的な接続をサポートするために 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

于 2014-01-13T23:36:16.997 に答える
0
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();
        }               
}

私はそれがうまくいくと思います。

于 2014-10-19T09:06:06.303 に答える