2011-06-22 120 views
11

我開始關注,這不是針對Android套管的教程,並得到這個:如何通過Android訪問SSL連接?

System.setProperty("javax.net.ssl.trustStore", "truststore"); 
    System.setProperty("javax.net.ssl.trustStorePassword", "password"); 

    SSLSocketFactory ssf = (SSLSocketFactory) SSLSocketFactory.getDefault(); 
    try { 
     Socket s = ssf.createSocket("192.168.2.11", 6543); 
     PrintWriter out = new PrintWriter(s.getOutputStream()); 
     while (true){ 
      out.println("SSL TEST"); 
      Log.d("DATA", "DATA SENT"); 
     } 



    } catch (UnknownHostException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

我想這可以歸結爲幾個問題:

  1. 我沒有我自己的信任存儲創建,但在網上搜索教程和東西,我不知道如何創建一個。有沒有一種方法可以創建或修改信任庫以獲取我需要的證書? (我使用的是自簽名證書,如果有什麼差別)

  2. 如何使事情與SSL握手平穩運行?現在,我得到的錯誤是:

     
    javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. 
    

    老實說,我真的不明白這意味着什麼。

  3. 我需要什麼樣的設置或文件來修改自己的Android設備上,以確保這方面發生的呢?

+0

你或許應該剛開始與Android的方式來做到這一點,而不是試圖修改非Android技術。 –

+0

我也嘗試將我從服務器獲得的keystore文件放在我的jdk/jre/lib/security文件夾中,然後更改信任存儲位置和密碼以匹配該文件,並且我得到了相同的異常。 – Matt

+0

等待!什麼是「Android的方式」? – Matt

回答

10

1)這取決於。你有在服務器端的自簽名證書,你正在嘗試驗證你的身份到Android設備?還是你在android端試圖驗證你的服務器的標識?如果是前者,那麼請訪問以下鏈接:http://www.codeproject.com/KB/android/SSLVerification_Android.aspx?display=Mobile

你要特別注意的地方,使密鑰存儲文件。

2)您得到該錯誤的原因是因爲它不信任您要連接的服務器,因爲您沒有正確創建信任庫,或者您正在連接到證書尚未添加到服務器的服務器信任。你究竟想要連接到什麼?

3)確保您在manifest.xml有<uses-permission android:name="android.permission.INTERNET" />

編輯 我的歉意,請參閱我對第一段所作的更改。

下面是初始化密鑰庫和信任

SSLcontext sslContext = SSLContext.getDefault(); 

KeyStore trustSt = KeyStore.getInstance("BKS"); 
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
InputStream trustStoreStream = this.getResources().openRawResource(R.raw.truststore); 
trustSt.load(trustStoreStream, "<yourpassword>".toCharArray()); 
trustManagerFactory.init(trustStre); 

KeyStore keyStore = KeyStore.getInstance("BKS"); 
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
InputStream keyStoreStream = this.getResources().openRawResource(R.raw.keystore); 
keyStore.load(keyStoreStream, "<yourpassword>".toCharArray()); 
keyManagerFactory.init(keyStore, "<yourpassword>".toCharArray()); 

sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); 
+0

[+1] 1)儘管(在查看本網站之前)我會調查一下,但我不確定我是否理解keystore和truststore之間的區別。 2)我可能沒有正確創建信任庫......我在JRE 中使用了keytool功能3)看起來像我至少得到了這個部分是正確的:0) – Matt

+1

嗨,對不起,我在第一段中犯了一個錯誤,請查看更改。 – Otra

+2

我認爲信任存儲和密鑰庫之間的區別在於信任存儲是我信任的證書列表,所以如果我在android端,我希望在我的信任存儲中擁有服務器證書。密鑰庫是我保持我的憑據驗證服務器的地方。在服務器端,信任存儲是我保存我信任的客戶端列表的地方,而密鑰存儲是我保存自己的憑據的位置。 – Otra

1

,除非對方是使用自簽名certifictes你不需要自己信任的一部分。 JRE附帶默認使用的信任庫,它信任所有主要CA頒發的證書。

+2

但我正在使用自簽名證書... – Matt

+0

@Matt,因此您需要創建一個信任庫。從JDK複製一個;將服務器證書導出到文件中;並將其導入新的信任庫。 – EJP