【发布时间】:2017-07-06 10:40:35
【问题描述】:
我正在尝试固定我的服务器的自签名证书。 我的 OkHttpClient 有两个参数,第一个是 ssl Socket Factory:
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();
【问题讨论】: