2012-05-23 18 views
0

我有一個實用程序SSLSocketFactory類,它基本上允許您切換,如果您想要信任所有證書和/或由於JDK錯誤而導致Deffie Hellman轉向。我最近添加了提供自己的SSLSocketFactory的選項,但似乎忘記了一些東西告訴任意SSLSocketFactories信任所有證書?

通過在創建套接字時簡單添加一些代碼來禁用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的信任所有證書,而無需更換呢?

+0

爲什麼'新的KeyManager [0]'和'不null'? (DH哪些錯誤是你指的是,順便說一句?) – Bruno

+0

@Bruno說實話,我複製這個從什麼地方,確信它的工作,然後用它做。我從來沒有能夠完全瞭解潛在的SSL Java代碼,所以我儘量不處理它的時候,我可以 – TheLQ

+1

如果你不完全瞭解底層的SSL代碼,你明白爲什麼這是一個壞主意,相信所有證書? – Bruno

回答

4

除了這個事實,盲目信任所有證書通常是一個壞主意(如果你想用SSL/TLS來保護通信),你使用的模式看起來很奇怪。

SSLContextSSLSocketFactory的工廠,該工廠又是SSLSocket的工廠。

如果需要,您可以使用SSLContext.setDefault(...)來設置默認的SSLContext(從Java 6開始):這會影響默認SSLSocketFactory,但可能不是更具體的。

你不能改變由現有的SSLSocketFactory實例SSLContext

除非您現有的SSLSocketFactory與默認實現有特定設置(例如在返回之前在創建的套接字上調整的東西)不同,否則您嘗試執行的操作似乎不符合預期的設計模式。

2

任意SSLSocketFactory的信任所有證書,而不必更換 它

號您設置自定義的「信任所有證書」經理,否則一個正在使用的默認「諮詢「Java JDK安裝中的默認信任庫cacerts

但是從安全的角度來看,如果你要沒有服務器認證,你還不如用普通TCP去避免SSL的開銷,因爲你實際上並沒有在所有的方式,你是以下任何安全性。

+1

嗯,我害怕這一點。我會留下這個問題,看看是否有其他人有另一種選擇,但如果沒有,我會接受你的回答 – TheLQ

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

} 
+1

再次閱讀問題:我已經用自己的替換SSLSocketFactory,但我想告訴一個現有工廠信任所有證書。我也沒有使用任何HTTP的東西,我使用原始套接字 – TheLQ

+6

@EJP信任所有證書**是這個問題**的要點。停止發送垃圾評論,說它不安全,我知道它是,我正在解決它 – TheLQ