У меня проблема с устройствами Android 4, которые получают следующее исключение при подключении к серверу:
java.security.cert.CertPathValidatorException: доверенная привязка для
путь сертификации не найден.
на com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake (OpenSSLSocketImpl.java:410)
по адресу okhttp3.internal.connection.RealConnection.connectTls (SourceFile: 319)
по адресу okhttp3.internal.connection.RealConnection.establishProtocol (SourceFile: 283)
по адресу okhttp3.internal.connection.RealConnection.connect (SourceFile: 168)
в okhttp3.internal.connection.StreamAllocation.findConnection (SourceFile: 257)
в okhttp3.internal.connection.StreamAllocation.findHealthyConnection (SourceFile: 135)
в okhttp3.internal.connection.StreamAllocation.newStream (SourceFile: 114)
по адресу okhttp3.internal.connection.ConnectInterceptor.intercept (SourceFile: 42)
по адресу okhttp3.internal.http.RealInterceptorChain.proceed (SourceFile: 147)
в okhttp3.internal.http.RealInterceptorChain.proceed (SourceFile: 121)
на okhttp3.internal.cache.CacheInterceptor.intercept (SourceFile: 93)
по адресу okhttp3.internal.http.RealInterceptorChain.proceed (SourceFile: 147)
в okhttp3.internal.http.RealInterceptorChain.proceed (SourceFile: 121)
по адресу okhttp3.internal.http.BridgeInterceptor.intercept (SourceFile: 93)
по адресу okhttp3.internal.http.RealInterceptorChain.proceed (SourceFile: 147)
в okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept (SourceFile: 126)
по адресу okhttp3.internal.http.RealInterceptorChain.proceed (SourceFile: 147)
в okhttp3.internal.http.RealInterceptorChain.proceed (SourceFile: 121)
в okhttp3.RealCall.getResponseWithInterceptorChain (SourceFile: 254)
по адресу okhttp3.RealCall.execute (SourceFile: 92)
Сертификат сервера от Cloudflare, я проверил его с помощью нескольких инструментов, таких как https://www.digicert.com/help/, и, похоже, все в порядке.
Но по какой-то причине я не понимаю, что он начал давать сбой в версиях Android 4.
Попробовал решение доверять всем сертификатам [LINK] , и это работает, но это, очевидно, имеет проблемы с безопасностью, такие как подвергание вашего приложения атаке "человек посередине"
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
okHttpBuilder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
Как я могу реализовать TrustManager с поведением по умолчанию, но в белый список входит только сертификат сервера.
Спасибо
Редактировать: по примеру OkHttp @ CustomTrust (Спасибо CommonsWare)
Использовал команду:
openssl s_client -showcerts -servername www.serverdomain.com -connect www.serverdomain.com:443
В цепочке сертификатов дали мне два сертификата в формате:
-----BEGIN CERTIFICATE-----
....
-----END CERTIFICATE-----
Заменил URL и сертификаты в примере на полученные, но он все еще не работает, есть идеи?