2010-10-31 44 views
15

在Java桌面應用程序的命令行中是否有類似的設置-D javax.net.debug=ssl,但對於Android?我試圖通過System.setProperty("javax.net.debug", "ssl");在代碼中設置它,但那不起作用。如何在Android平臺上啓用SSL調試?

如果沒有辦法來啓用此屬性,是否至少有另一種方式來調試SSL連接的客戶端?

編輯:爲了澄清,這是指原始SSL套接字(SSLSocket和SSLSocketFactory),而不是Apache庫或任何其他網絡庫。

+0

我也想知道,但我找不到任何線索。 :S – gnclmorais 2011-02-03 18:51:46

回答

1

在這一點上,似乎沒有成爲一個辦法做到這一點。但無論如何,我們很快就會切換到Netty庫,它具有更詳細的日誌記錄功能。

因此,此問題的解決方案(不是很好)完全不是使用SSLSocket,而是使用更好的網絡圖書館。

+1

如果有人發現,實際上已經找到了一種啓用SSLSocket握手調試的方法,請添加您的答案,而我將接受您的答案。 – 2012-01-13 19:07:40

0

如果您使用Apache HttpClient(通過導入jar文件),則可以通過在Eclipse中設置環境變量來啓用日誌記錄。如果使用Commons Logging,日誌將打印到控制檯。但是,只有在模擬器中而不是在設備上運行應用程序時,這纔有效。不知道這有助於。

http://hc.apache.org/httpcomponents-client-ga/logging.html

+0

對不起,我應該已經更清楚了,我沒有使用Apache庫,這是與原始SSL套接字。在桌面Java上,在SSL握手上進行調試非常簡單,但在Android上它似乎是不可能的。 – 2011-03-17 18:43:37

1

你可以寫一個TrustManager類來處理它。 例如:

ClientConnectionManager cm = new BasicClientConnectionManager(); 
cm.getSchemeRegistry().register(createHttpsScheme()); 
DefaultHttpClient client = new DefaultHttpClient(cm); 
String url = "https://your domain/your url"; 
HttpGet get = new HttpGet(url); 
HttpResponse resp = client.execute(get); 

etc.. 

public static Scheme createHttpsScheme() { 
     SSLContext context = SSLContext.getInstance("TLS"); 
     context.init(null, new TrustManager[] { 
       new TestTrustManager() 
     }, new SecureRandom()); 

     SSLSocketFactory sf = new SSLSocketFactory(context); 
     return new Scheme("https", 443, sf); 
} 

INT TestTrustManager.java可以打印鏈是這樣的:

public class TestTrustManager implements X509TrustManager { 
    @Override 
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 

     for (int i = 0; i < chain.length; ++i) { 
     System.out.println(chain[i]); 
     } 

     decorated.checkServerTrusted(chain, authType); 
    } 
} 
0

我已經找到了一個有用的調試輔助手段是寫周圍X509KeyManager和X509TrustManager的包裝,委託調用原始實現,同時記錄結果,例如:

 TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
     tmf.init(ks); 

     KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
     kmf.init(ks, null); 

     TrustManager[] tms = WrapTrustManager.WrapArray(tmf.getTrustManagers()); 
     KeyManager[] kms = WrapKeyManager.WrapArray(kmf.getKeyManagers()); 
     SSLContext context = SSLContext.getInstance("TLS"); 
     context.init(kms, tms, null); 

     ....setSocketFactory(context.getSocketFactory()); 

WrapTrustManager和WrapKeyManager的實現是pret ty直截了當,但要警告他們使用異常來指示失敗,因此在記錄結果時不要吞下異常是很重要的。

請注意,該接口使用空的KeyManager和TrustManager接口,並且需要將這些接口動態上傳到X509KeyManager和X509TrustManager。