我使用Retrofit2
與RxJava2
和OkHttp3
作出HTTPS
調用用於測試SSL
證書的內部服務器的有效證書,但我總是得到一個異常說明:OkHttp3:SSL證書不被視爲
HTTP FAILED: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
按照Google developer documentation,有3個原因,這可能發生(未知CA,自簽名證書或服務器配置缺少中間CA)
我canno T發表的URL,因爲它是一個內部測試服務器,但在我的電腦或我的手機在Chrome中正常工作在瀏覽器中打開的URL,這是我可以從證書看:
因此,我認爲它不能是選項1,因爲瀏覽器識別證書,只有我的應用程序和OkHttp看起來不那麼如此,因爲它沒有自簽名證書,選項2也不應該是原因。
這是怎麼我的OkHttp
客戶端由Dagger
提供:
@Provides
@PerApplication
OkHttpClient provideOkHttpClient(@ApplicationContext Context context) {
int cacheSize = 10 * 1024 * 1024; // 10 MiB
File cacheDirectory = new File(context.getCacheDir().getAbsolutePath(), "HttpCache");
ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.cipherSuites(
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
.build();
OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder()
.connectionSpecs(Collections.singletonList(spec))
.readTimeout(60, TimeUnit.SECONDS)
.connectTimeout(10, TimeUnit.SECONDS)
.cache(new Cache(cacheDirectory, cacheSize));
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
httpClientBuilder.addInterceptor(loggingInterceptor);
}
return httpClientBuilder.build();
}
我加入了CollectionSpec
定義,我使用TLS 1.2,但是這並沒有區別,我還是收到了信任錨錯誤。
爲了使用ssl證書,我還需要設置其他的東西嗎?任何想法爲什麼證書不被接受?
「因此,我認爲它不能成爲選項1,因爲瀏覽器識別證書」 - 我不會假定Chrome接受的內容與Android SDK應用程序在根證書頒發機構方面接受的內容匹配。 – CommonsWare
你是對的,這是有道理的。 – Eve
@Eve我面臨同樣的,並已回答http://stackoverflow.com/a/42392679/2870088。這是選項3缺少中級證書頒發機構。是的,瀏覽器會緩存中間證書,並在不同的網站之間使用它們。因此,如果缺少中間證書,隨機用戶將收到信任錯誤,而其他用戶則不會。 http://superuser.com/questions/351516/do-intermediate-certificates-get-cached-in-firefox –