2012-12-13 53 views
1

我想使用位於p12包中的自定義證書進行https連接。我已經在iPhone上做過了(所以我可以驗證,證書,服務器等一切正常),但是在Android上遇到了一些問題。使用自定義證書的Android https連接

我跟着How to request a URL that requires a client certificate for authentication answear,但作爲一個結果,我得到以下異常:

12-13 12:32:44.545:W/System.err的(4407): javax.net.ssl中.SSLHandshakeException: java.security.cert.CertPathValidatorException:未找到 證書路徑的信任錨點。 12-13 12:32:44.545:W/System.err(4407): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:374) 12-13 12:32 :44.545:W/System.err(4407):at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:209) 12-13 12:32:44.545:W/System.err(4407):at libcore.net.http.HttpsURLConnectionImpl $ HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:478) 12-13 12:32:44.545:W/System.err的(4407):在 libcore.net.http.HttpsURLConnectionImpl $ HttpsEngine。連接(HttpsURLConnectionImpl.java:433) 12-13 12:32:44.545:W/System.err(4407):at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:289) 12-13 12:32:44.550:W/System.err(4407):at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:239)12-13 12:32:44.550:W/System .err(4407):at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80) 12-13 12:32:44.550:W/System.err(4407):at libcore.net.http .HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:165) 12-13 12:32:44.550:W/System.err(4407):at com.geckolab.httptestandroid.MainActivity.downloadUrlHttps(MainActivity.java:172) 12 -13 12:32:44.550:W/System.err(4407):at com.geckolab.httptestandroid.MainActivity.access $ 0(MainActivity.java:151) 12-13 12:32:44.550:W/System。 err(4407):at com.geck olab.httptestandroid.MainActivity $ DownloadWebPageTextHttps.doInBackground(MainActivity.java:99) 12-13 12:32:44.550:W/System.err(4407):at com.geckolab.httptestandroid.MainActivity $ DownloadWebPageTextHttps.doInBackground(MainActivity .java:1) 12-13 12:32:44.550:W/System.err(4407):at android.os.AsyncTask $ 2.call(AsyncTask.java:287)12-13 12:32:44.550: W/System.err(4407):at java.util.concurrent.FutureTask $ Sync.innerRun(FutureTask.java:305) 12-13 12:32:44.555:W/System.err(4407):at java.util.concurrent.FutureTask.run(FutureTask.java:137)12-13 12:32:44.555:W/System.err(4407):at android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask .java:230)12-13 12:32:44.555:W/System.err(4407):at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 12-13 12:32:44.555:W/System.err( 4407):在 java.util.concurrent.ThreadPoolExecutor中$ Worker.run(ThreadPoolExecutor.java:569) 12-13 12:32:44.555:W/System.err的(4407):在 java.lang.Thread中。運行(Thread.java:856)12-13 12:32:44.555: W/System.err(4407):導致者: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException:Trust anchor找不到 認證路徑。 12-13 12:32:44.560:W/System.err(4407): at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl。(TrustManagerImpl.java:192) 12-13 12:32:44.560:W/System.err ) 12-13 12:32:44.560:W/System.err(4407):at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:573) 12-13 12: 32:44.560:W/System.err(4407):at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method)12-13 12:32:44.560:W/System.err( 4407):at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:371) 12-13 12:32:44.560:W/System.err(4407):... 18更多12-13 12:32:44.560:W/Syst em.err(4407):導致: java.security.cert.CertPathValidatorException:未找到 證書路徑的信任錨點。 12-13 12:32:44.560:W/System.err的(4407): ...... 23多個

我的連接代碼看起來如下:

KeyStore ks = KeyStore.getInstance("PKCS12"); 
     ks.load(context.getResources().openRawResource(R.raw.gecko_cert_1), "gecko_cert_1".toCharArray()); 
     KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509"); 
     kmf.init(ks, "gecko_cert_1".toCharArray()); 
     SSLContext sc = SSLContext.getInstance("TLS"); 
     sc.init(kmf.getKeyManagers(), null, null); 


     //request 
     URL serverURL = new URL(myurl); 
     HttpsURLConnection conn = (HttpsURLConnection)serverURL.openConnection(); 
     conn.setSSLSocketFactory(sc.getSocketFactory()); 
     //conn.setHostnameVerifier(DO_NOT_VERIFY); 
     conn.setReadTimeout(10000 /* milliseconds */); 
     conn.setConnectTimeout(15000 /* milliseconds */); 
     conn.setRequestMethod("GET"); 
     conn.setDoInput(true); 
     // Starts the query 
     conn.connect(); 

乾杯, 馬爾辛

+0

在你的文章中你提到你有在iOS中工作的證書認證。你能提供你在iOS上使用證書認證的代碼嗎? – njtman

回答

-4

它現在適用於我。

添加以下代碼段上的連接方法的頂部:

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

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

      public X509Certificate[] getAcceptedIssuers() { 
       return new X509Certificate[0]; 
      } 
     } }; 

然後交換行:

sc.init(kmf.getKeyManagers(), null, null); 

到:

sc.init(kmf.getKeyManagers(), tm, null); 

我也未註釋這個線:

conn.setHostnameVerifier(DO_NOT_VERIFY); 

乾杯, Marcin

+6

這是壞的,壞的,壞的。它將允許和信任*任何*證書,打開您的應用程序以進行中間人攻擊。獲取服務器證書,將其添加到信任庫並初始化您的連接。一些細節和代碼在這裏:http://nelenkov.blogspot.jp/2011/12/using-custom-certificate-trust-store-on.html –

相關問題