Bir Android uygulamasında com.squareup.retrofit:retrofit:1.9.0
ile com.squareup.okhttp:okhttp:2.4.0
'u kullanarak, kendinden imzalı bir sertifika kullanan HTTPS üzerinden bir sunucu REST API'siyle iletişim kurmaya çalışıyorsunuz.Sertifika Android'de OkHttp ile çalışmayan sertifika
Sunucu anahtar deposunda özel bir anahtar ve 2 sertifika, sunucunun ve bir kök sertifikası vardır. openssl s_client
çıktı - Android uygulaması At
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]
, OkHttp kök sertifikanın SHA1 imzasıyla başlatıldığını -
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();
Ama bir istek göndermeye çalışırken durumla başarısız -
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)
sslSocket.startHandshake()
çalışırken com.squareup.okhttp.internal.http.SocketConnector
adresinden atılır, CertificatePinner
alınan sertifikaları kontrol etmek için kullanılır ficates.
Sunucunun openssl
ve curl --cacert root.pem
ile doğru şekilde yüklenmiş sertifikalarının olduğundan emin oldum.
Peki neden sağlanan sertifikaların iyi olup olmadığını kontrol etmeye çalışan OkHttp neden bir istisna atar?
Yup. Sertifika sabitleme mevcut sertifika doğrulamasının yerini almaz; onu tamamlar. Müşterinizi sertifikanıza güvenecek şekilde yapılandırmanız gerekir; Testlerde bolca örnek var! –
@JesseWilson and @Kof: Bir soru sorabilir miyim, bilinen bir CA, Android telefonunda başarılı bir şekilde yüklenmiş bir CA anlamına gelir ('Güvenilir kimlik bilgileri - Kullanıcı 'bölümünde görebilirim? Teşekkürler – BNK
Muhtemelen bir CA Cihazın güvenilen CA veritabanında imzası var – Kof