2015-08-30 34 views
14

Sử dụng com.squareup.okhttp:okhttp:2.4.0 với com.squareup.retrofit:retrofit:1.9.0 trên ứng dụng Android, cố gắng liên lạc với máy chủ REST API qua HTTPS, sử dụng chứng chỉ tự ký.Chứng chỉ ghim không hoạt động với OkHttp trên Android

Kho lưu trữ máy chủ có khóa cá nhân và 2 chứng chỉ, chứng chỉ của máy chủ và chứng chỉ gốc. openssl s_client đầu ra -

Certificate chain 
0 s:/C=...OU=Dev/CN=example.com 
    i:/C=... My CA/[email protected] 
1 s:/C=... My CA/[email protected] 
    i:/C=... My CA/[email protected] 

Tại ứng dụng Android, OkHttp được khởi tạo với chữ ký SHA1 chứng chỉ gốc của -

CertificatePinner certificatePinner = new CertificatePinner.Builder() 
     .add("example.com", "sha1/5d...3b=") 
     .build(); 

OkHttpClient client = new OkHttpClient(); 
client.setCertificatePinner(certificatePinner); 

RestAdapter restAdapter = new RestAdapter.Builder() 
     .setEndpoint("https://example.com") 
     .setClient(new OkClient(client)) 
     .build(); 

Nhưng khi cố gắng gửi một yêu cầu không thành công với ngoại lệ -

retrofit.RetrofitError: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. 
     at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:395) 
     at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:240) 
     at java.lang.reflect.Proxy.invoke(Proxy.java:397) 
     at $Proxy1.report(Unknown Source) 
     ... 
     at android.os.AsyncTask$2.call(AsyncTask.java:288) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
     at java.lang.Thread.run(Thread.java:818) 
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. 
     at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:306) 
     at com.squareup.okhttp.internal.http.SocketConnector.connectTls(SocketConnector.java:103) 
     at com.squareup.okhttp.Connection.connect(Connection.java:143) 
     at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:185) 
     at com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128) 
     at com.squareup.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341) 

Nó được ném tại com.squareup.okhttp.internal.http.SocketConnector khi thử sslSocket.startHandshake(), thậm chí trước khi CertificatePinner được sử dụng để kiểm tra certi đã nhận ficates.

Tôi đã đảm bảo máy chủ có chứng chỉ được cài đặt chính xác bằng cách sử dụng openssl và với curl --cacert root.pem.

Vậy tại sao OkHttp lại ném ngoại lệ trước khi thử kiểm tra xem các chứng chỉ được cung cấp có ổn không?

Trả lời

5

OkHttp không hỗ trợ chứng chỉ tự ký.

Khi sử dụng chứng chỉ được ký bởi một CA đã biết, bắt tay thành công và sau đó CertificatePinner đảm bảo chuỗi chứng chỉ chứa ít nhất một trong các chữ ký được cung cấp. Nếu không xuất hiện, nó sẽ ném một ngoại lệ, dừng yêu cầu.

Vì vậy, có thể sử dụng một chứng chỉ được ký bởi một CA đã biết và ghim một trong các chứng chỉ để đảm bảo chúng tôi đang nói chuyện với đúng máy chủ.

+2

Yup. Việc ghim chứng chỉ không thay thế xác minh chứng chỉ hiện có; nó bổ sung nó. Bạn cần định cấu hình ứng dụng khách của mình để tin cậy chứng chỉ của mình; có rất nhiều ví dụ trong các bài kiểm tra! –

+0

@JesseWilson và @Kof: Tôi có thể đặt câu hỏi không, 'một CA đã biết 'có nghĩa là một CA được cài đặt thành công trong điện thoại Android hay không (Tôi có thể thấy nó trong' Thông tin đáng tin cậy - Người dùng'? Cảm ơn – BNK

+0

Có thể, đó là CA thiết bị có chữ ký được cài đặt trong cơ sở dữ liệu CA đáng tin cậy của nó – Kof

3

OkHttp hỗ trợ chứng chỉ tự ký.

Vui lòng kiểm tra this answer để tìm hiểu cách tạo SslSocket chỉ ủy thác chứng chỉ của bạn.

+2

Một vị trí khác để xem mã ví dụ nằm trong repo công thức của OkHttp: [CustomTrust.java] (https://github.com/square/okhttp/blob/master/samples/guide /src/main/java/okhttp3/recipes/CustomTrust.java) Nó cung cấp mã làm việc chung chung hơn. – Anonsage

Các vấn đề liên quan