7

我知道這個主題在很多地方討論,但我經歷了幾乎所有的人去了之後,我決定創建我的第一個問題StackOverflow上...Android的自簽名證書:信任錨認證路徑沒有找到

的問題是以下內容:

我想連接到一個安全的web服務(HTTPS),其使用證書來限制訪問,和用戶名/密碼對用戶進行認證。所以我有一個客戶端證書(p12文件)和一個服務器證書(pem或der文件)。我嘗試使用HttpURLConnection類,因爲據我所知,Apache庫不會在Android上受到支持。

所以這是我實現(serverCert和clientCert是完整路徑到我的文件):

 // Load CAs from our reference to the file 
     CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
     InputStream caInput = new BufferedInputStream(new FileInputStream(serverCert)); 
     X509Certificate serverCertificate; 

     try { 
      serverCertificate = (X509Certificate)cf.generateCertificate(caInput); 
      System.out.println("ca=" + serverCertificate.getSubjectDN()); 
     } finally { 
      caInput.close(); 
     } 
     Log.d(TAG, "Server Cert: " + serverCertificate); 

     // Create a KeyStore containing our trusted CAs 
     KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
     trustStore.load(null); 
     trustStore.setCertificateEntry("my ca", serverCertificate); 

     //Load the Client certificate in the keystore 
     KeyStore keyStore = KeyStore.getInstance("PKCS12"); 
     FileInputStream fis = new FileInputStream(clientCert); 
     keyStore.load(fis,CLIENT_PASSWORD); 

     // Create a TrustManager that trusts the CAs in our KeyStore 
     TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
     tmf.init(trustStore); 

     //Build the SSL Context 
     KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
     kmf.init(keyStore, pref.getString(Constants.clientCertificatePassword, "").toCharArray 

()); 


    //Create the SSL context 
       SSLContext sslContext = SSLContext.getInstance("TLS"); 
       sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 
... 
    //And later, we use that sslContext to initiatize the socketFactory 

       urlConnection = (HttpsURLConnection) requestedUrl.openConnection(); 
     urlConnection.setSSLSocketFactory(CertificateManager.getInstance().getSslContext().getSocketFactory()); 
... 

因此,我可以創造我的SSLContext,並顯示我的兩個證書的內容。但是,當我嘗試執行我的HTTPS連接時,出現以下異常:

09-23 13:43:30.283:W/System.err(19422):javax.net.ssl.SSLHandshakeException:java.security。 cert.CertPathValidatorException:找不到證書路徑的信任錨點。

你們中的一個曾經遇到以下錯誤嗎?你的解決方案是什麼?

這些網站我的經歷(沒有成功):

http://blog.chariotsolutions.com/2013/01/https-with-client-certificates-on.html

http://nelenkov.blogspot.ch/2011/12/using-custom-certificate-trust-store-on.html

+0

我也試過這個解決方案(http://nelenkov.blogspot.ch/2011/12/using-custom-certificate-trust-store-on.html),但仍然是相同的消息...是否有可能服務器配置不好? – TheOnlyYam

+2

嘿,這是相當長的一段時間,但你找到了解決方案嗎?我也有同樣的問題。我有一個pem和一個p12文件。 – Wicked161089

回答

1

在你的代碼的創建和初始化SSLContext,但不使用它。也許你應該更換:

urlConnection.setSSLSocketFactory(CertificateManager.getInstance().getSslContext().getSocketFactory()); 

通過

urlConnection.setSSLSocketFactory(sslContext.getSocketFactory()); 

我也建議你如果可能的選項-Djavax.net.debug=all傳遞給JVM。它將在標準輸出上打印關於SSL連接和握手的詳細信息。

相關問題