要在OkHttpClient使用JRE信任库的基础上加上自定义证书,可以使用自定义TrustManager的方式来实现。
首先,需要创建一个X509TrustManager的实现类,这个实现类需要实现checkServerTrusted方法,用于检查服务端返回的证书是否是受信任的证书。在实现checkServerTrusted方法时,可以先调用JRE信任库中的X509TrustManager的checkServerTrusted方法,再加上自定义的检查逻辑,确保返回的证书是受信任的。具体实现如下:
public static class CustomTrustManager implements X509TrustManager {
private X509TrustManager defaultTrustManager;
private X509TrustManager localTrustManager;
public CustomTrustManager() throws Exception {
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init((KeyStore) null);
defaultTrustManager = findX509TrustManager(tmf);
localTrustManager = createLocalTrustManager();
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
throw new UnsupportedOperationException();
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
try {
defaultTrustManager.checkServerTrusted(chain, authType);
} catch (CertificateException ce) {
localTrustManager.checkServerTrusted(chain, authType);
}
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return defaultTrustManager.getAcceptedIssuers();
}
private X509TrustManager findX509TrustManager(TrustManagerFactory tmf) {
TrustManager[] trustManagers = tmf.getTrustManagers();
for (TrustManager tm : trustManagers) {
if (tm instanceof X509TrustManager) {
return (X509TrustManager) tm;
}
}
return null;
}
private X509TrustManager createLocalTrustManager() throws Exception {
KeyStore localTrustStore = KeyStore.getInstance(KeyStore.getDefaultType());
localTrustStore.load(null, null);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Resource resource = ResourcePatternUtils.getResourcePatternResolver(new DefaultResourceLoader()).getResource("/sectigo_root_certificates_1199354.crt");
InputStream caInput = resource.getInputStream();
try {
Certificate ca = cf.generateCertificate(caInput);
localTrustStore.setCertificateEntry("custom-cert", ca);
} finally {
caInput.close();
}
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(localTrustStore);
return findX509TrustManager(tmf);
}
}
在上面的实现中,CustomTrustManager类实现了X509TrustManager接口,并包含了两个X509TrustManager实例:defaultTrustManager和localTrustManager。defaultTrustManager是从JRE信任库中获取的X509TrustManager,localTrustManager是自定义的TrustManager。在checkServerTrusted方法中,先调用defaultTrustManager的checkServerTrusted方法,如果检查不通过,则调用localTrustManager的checkServerTrusted方法进行自定义的检查。
接下来,可以将自定义的TrustManager实例添加到OkHttpClient中:
public static void main(String[] args) throws Exception {
CustomTrustManager customTrustManager = new CustomTrustManager();
// 创建SSLContext
SSLContext sslContext = Platform.get().getSSLContext();
sslContext.init(null, new TrustManager[] { customTrustManager }, null);
// 创建OkHttpClient
OkHttpClient httpClient = new OkHttpClient.Builder()
.sslSocketFactory(sslContext.getSocketFactory(), customTrustManager)
.build();
final Request request = new Request.Builder().url("https://www.baidu.com").build();
httpClient.newCall(request).execute();
}
你投入得越多,就能得到越多得价值