7

Tôi biết vấn đề này sẽ được thảo luận ở nhiều nơi, nhưng sau khi tôi đã đi qua hầu hết trong số họ, tôi đã quyết định để tạo ra câu hỏi StackOverflow đầu tiên của tôi ...Android tự ký giấy chứng nhận: Trust neo cho con đường xác nhận không tìm thấy

Sự cố xảy ra sau đây:

Tôi muốn kết nối với dịch vụ web bảo mật (https) sử dụng chứng chỉ để hạn chế quyền truy cập và tên người dùng/mật khẩu để xác thực người dùng. Vì vậy, tôi có một khách hàng cert (p12 tập tin) và một máy chủ cert (pem hoặc der tập tin). Tôi cố gắng sử dụng lớp HttpURLConnection, bởi vì từ những gì tôi đã nghe, thư viện Apache sẽ không còn được hỗ trợ trên Android nữa.

Vì vậy, đây là hiện thực của tôi (serverCert và clientCert có đầy đủ đường dẫn đến tập tin của tôi):

 // 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()); 
... 

Vì vậy, tôi có thể tạo SSLContext của tôi, và hiển thị nội dung hai giấy chứng nhận của tôi. Nhưng khi tôi cố gắng thực hiện kết nối HTTPS của mình, tôi nhận được ngoại lệ sau:

09-23 13: 43: 30.283: W/System.err (19422): javax.net.ssl.SSLHandshakeException: java.security. cert.CertPathValidatorException: Trust anchor cho đường dẫn chứng nhận không tìm thấy.

Bạn đã từng gặp lỗi sau chưa? Giải pháp của bạn là gì?

Đây là những trang web tôi đã đi qua (không thành công):

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

Tôi cũng đã thử giải pháp này (http://nelenkov.blogspot.ch/2011/12/using-custom-certificate-trust-store-on.html), nhưng vẫn cùng một thông báo ... Có thể là máy chủ không được cấu hình tốt? – TheOnlyYam

+2

Hey, khá lâu rồi, nhưng bạn có tìm được giải pháp không? Tôi có cùng một vấn đề. Tôi có một pem và một tập tin p12. – Wicked161089

Trả lời

1

Trong mã của bạn của bạn đang tạo và khởi tạo một SSLContext nhưng không sử dụng nó. Có lẽ bạn nên thay thế:

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

bởi

urlConnection.setSSLSocketFactory(sslContext.getSocketFactory()); 

Tôi cũng đề nghị bạn nếu có thể để vượt qua các tùy chọn -Djavax.net.debug=all để JVM. Nó sẽ in thông tin chi tiết về kết nối SSL và bắt tay vào đầu ra tiêu chuẩn.