Я пытаюсь подключить самозаверяющий сертификат моего сервера. Мой OkHttpClient принимает два параметра, первый из них является SSL Оправа Factory:Okhttp3 - Принять все сертификаты и использовать сертификатPinner
final TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
@SuppressLint("TrustAllX509TrustManager")
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {}
@SuppressLint("TrustAllX509TrustManager")
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
};
// Install the all-trusting trust manager
SSLContext sslContext;
try {
sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
} catch (NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
FirebaseCrash.report(e);
return null;
}
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
Во-вторых, сертификат передник:
new CertificatePinner.Builder()
.add("bogus.com", "sha1/BOGUS")
.build()
Примечание: если я не добавить certificatePinner, то все работает хорошо. Проблема заключается в том, что, когда запрос запускается на выполнение, CertificatePinner.check() вызывается:
if (pins.isEmpty()) return;
Очевидно, что если я установил (непустое) certificatePinner, метод не будет останавливаться на достигнутом и будет продолжать. Затем следует проверить, что «по крайней мере один из сертификатов, закрепленных за моим именем хоста, является доверенным сертификатом».
Проблема заключается в том, что я передал пустой массив в getAcceptedIssuers для моего TrustManager - это означает, что самозаверяющий сертификат вызовет исключение, поскольку он явно не доверял «getAcceptedIssues». Похоже, что невозможно связать сертификат, которому явно не доверяют в «getAcceptedIssuers».
Есть ли способ обойти это? Это по дизайну?
Это, как я строю мой OkHttpClient:
OkHttpClient client = new OkHttpClient.Builder()
.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0])
.certificatePinner(certPinner)
.readTimeout(10, TimeUnit.SECONDS)
.connectTimeout(10, TimeUnit.SECONDS)
.build();
Код, который вы предоставили, определенно помог мне, хотя это не совсем соответствует моему первоначальному вопросу. Благодаря вашей помощи я действительно создал действительный TrustManager. – geecko
Да, я пытался ответить на то, что, как я думал, вы пытаетесь сделать, добавить самозаверяющий сертификат, чтобы у вас было безопасное соединение, но специально для этого. Принятие всех сертификатов, а затем попытка подключения, не похоже на типичный вариант использования. –