OkHttpClient在使用JRE信任库的基础上加上自定义证书
要在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(); }
你投入得越多,就能得到越多得价值