0

我有一个实用程序 SSLSocketFactory 类,如果你想信任所有证书和/或由于 JDK 错误而转向 Deffie Hellman,它基本上允许你切换。我最近添加了提供您自己的 SSLSocketFactory 的选项,但似乎忘记了一些东西

在工厂中禁用 Diffie Hellman 很容易,只需在创建套接字时添加一些代码即可。但是,为了信任所有证书,我用不同的证书替换了工厂

    public UtilSSLSocketFactory trustAllCertificates() {
            if (trustingAllCertificates)
                    //Already doing this, no need to do it again
                    return this;
            trustingAllCertificates = true;
            try {
                    TrustManager[] tm = new TrustManager[]{new TrustingX509TrustManager()};
                    SSLContext context = SSLContext.getInstance("SSL");
                    context.init(new KeyManager[0], tm, new SecureRandom());
                    wrappedFactory = (SSLSocketFactory) context.getSocketFactory();
            } catch (Exception e) {
                    throw new RuntimeException("Can't recreate socket factory that trusts all certificates", e);
            }
            return this;
    }

有没有办法告诉任意 SSLSocketFactory 信任所有证书而不替换它?

4

3 回答 3

4

除了盲目信任所有证书通常是一个坏主意(如果您希望使用 SSL/TLS 来保护通信)这一事实之外,您使用的模式似乎很奇怪。

SSLContext是工厂SSLSocketFactory,而工厂又是工厂SSLSocket

如果需要,您可以使用 : 设置默认值SSLContext(从 Java 6 开始),SSLContext.setDefault(...)这将影响默认值SSLSocketFactory,但可能不会更具体。

您无法更改SSLContext现有SSLSocketFactory实例使用的。

除非您现有SSLSocketFactory的与具有特定设置的默认实现不同(例如,在返回它之前您会在创建的套接字上进行调整),否则您尝试做的似乎不适合这里的预期设计模式。

于 2012-05-23T18:24:58.977 回答
2

任意 SSLSocketFactory 信任所有证书而不替换它

不可以。您必须设置自己的自定义“信任所有证书”管理器,否则将使用默认的管理器,它会“咨询”cacerts您的 JDK 安装中的 java 的默认信任库。

但是从安全的角度来看,如果您不打算进行服务器身份验证,那么您最好使用纯 TCP 并避免 SSL 开销,因为您实际上并没有任何安全措施。

于 2012-05-23T17:24:04.733 回答
-1

试试这个代码......它是一个工作代码,在你的代码中使用这个类,就像这样

HttpClient client = MySSLSocketFactory.getNewHttpClient();

这是代码

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;

public class MySSLSocketFactory extends SSLSocketFactory {
    SSLContext sslContext = SSLContext.getInstance("TLS");

    public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
       super(truststore);

       TrustManager tm = new X509TrustManager() {
           public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
           }

           public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
           }

           public X509Certificate[] getAcceptedIssuers() {
               return null;
           }
       };

       sslContext.init(null, new TrustManager[] { tm }, null);
    }

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
       return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
    }

    @Override
    public Socket createSocket() throws IOException {
       return sslContext.getSocketFactory().createSocket();
    }


public static HttpClient getNewHttpClient() {
    try {
       KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
       trustStore.load(null, null);

       SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
       sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

       HttpParams params = new BasicHttpParams();
       HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
       HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

       SchemeRegistry registry = new SchemeRegistry();
       registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
       registry.register(new Scheme("https", sf, 443));

       ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

       return new DefaultHttpClient(ccm, params);
    } catch (Exception e) {
       return new DefaultHttpClient();
    }
}

}
于 2012-05-23T17:51:31.147 回答