首先參考
Okhttp 訪(fǎng)問(wèn)自簽名證書(shū) HTTPS 地址解決方案
上面這篇博客伐庭,解決了訪(fǎng)問(wèn)自簽名證書(shū)的問(wèn)題。
但是有時(shí)候我們要訪(fǎng)問(wèn)過(guò)多域名樊拓,每個(gè)域名的證書(shū)又不一樣我們應(yīng)該怎樣做呢
private SSLSocketFactory createSSLSocketFactory() {
SSLSocketFactory ssfFactory = null;
try {
MyTrustManager mMyTrustManager = new MyTrustManager();
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, new TrustManager[]{mMyTrustManager}, new SecureRandom());
ssfFactory = sc.getSocketFactory();
} catch (Exception ignored) {
ignored.printStackTrace();
}
return ssfFactory;
}
//實(shí)現(xiàn)X509TrustManager接口
public class MyTrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
//實(shí)現(xiàn)HostnameVerifier接口
private class TrustAllHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
/**
* 獲去信任自簽證書(shū)的trustManager
*
* @param ins 自簽證書(shū)輸入流
* @return 信任自簽證書(shū)的trustManager
* @throws GeneralSecurityException
*/
private X509TrustManager trustManagerForCertificates(InputStream... ins)
throws GeneralSecurityException {
//創(chuàng)建證書(shū)工廠
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
//通過(guò)證書(shū)工廠得到自簽證書(shū)對(duì)象集合
Collection<Certificate> certificates = new ArrayList<>();
for (InputStream inputStream : ins) {
certificates.addAll(certificateFactory.generateCertificates(inputStream));
}
if (certificates.isEmpty()) {
throw new IllegalArgumentException("expected non-empty set of trusted certificates");
}
//為證書(shū)設(shè)置一個(gè)keyStore
char[] password = "password".toCharArray(); // Any password will work.
KeyStore keyStore = newEmptyKeyStore(password);
int index = 0;
//將所有證書(shū)放入證書(shū)放入keystore中
for (Certificate certificate : certificates) {
String certificateAlias = Integer.toString(index++);
keyStore.setCertificateEntry(certificateAlias, certificate);
}
// Use it to build an X509 trust manager.
//使用包含自簽證書(shū)信息的keyStore去構(gòu)建一個(gè)X509TrustManager
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, password);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length == 0) {
throw new IllegalStateException("Unexpected default trust managers:"
+ Arrays.toString(trustManagers));
}
return ((X509TrustManager) trustManagers[0]);
}
private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {
try {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream in = null; // By convention, 'null' creates an empty key store.
keyStore.load(null, password);
return keyStore;
} catch (IOException e) {
throw new AssertionError(e);
}
}
trustManagerForCertificates.(InputStream...ins)為證書(shū)的輸入流
比如證書(shū)文件有兩個(gè) 1.crt 和2.crt
X509TrustManager x509TrustManager = trustManagerForCertificates(
new FileInputStream(new File("1.crt")), new FileInputStream(new File("2.crt"))
);
//獲取到SSLSocketFactory和X509TrustManager
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.sslSocketFactory(createSSLSocketFactory(),x509TrustManager )
.build();