最近為了網(wǎng)絡(luò)安全构资,項目決定把以前的http請求全部換成https,本來用公司級生成的正式證書什么問題的不會有遮糖,也不用考慮新增代碼冕广。不過貌似證書很貴落追,所有采用了自己生成證書盈滴,那么事就這么來了。
先向服務(wù)器大哥討要證書.cer文件,可以放在raw或者assets文件夾下面轿钠。用下面的方法獲取證書數(shù)據(jù)
在application類中巢钓,配置okhttpclient之前先讀取信息
添加證書
主要會用到下面這個方法
private static SSLSocketFactorygetSocketFactory(List certificates) {
try {
????????CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
? ? ? ? KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
? ? ? ? keyStore.load(null);
? ? ? ? try {
????????????????for (int i =0, size = certificates.size(); i < size; ) {
????????????????InputStream certificate = certificates.get(i);
? ? ? ? ? ? ? ? String certificateAlias = Integer.toString(i++);
? ? ? ? ? ? ? ? keyStore.setCertificateEntry(certificateAlias, certificateFactory
.generateCertificate(certificate));
? ? ? ? ? ? ? ? if (certificate !=null)
????????????????????certificate.close();
? ? ? ? ? ????? }
????????}catch (IOException e) {
????????????????e.printStackTrace();
? ? ? ? }
SSLContext sslContext = SSLContext.getInstance("TLS");
TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
?trustManagerFactory.init(keyStore);
?sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
?return sslContext.getSocketFactory();
? ? }catch (Exception e) {
e.printStackTrace();
? ? }
return null;
}
處理這個問題的時候發(fā)現(xiàn)可能還會碰到更復(fù)雜更安全的方式,如雙向證書認證等疗垛,給大家放個鏈接症汹,感覺這個介紹的更加具體仔細
http://blog.csdn.net/quincyjiang/article/details/76273446
運行報錯的幾個異常處理
1.報錯javax.net.ssl.SSLHandshakeException,這個異常主要會出現(xiàn)兩種情況
javax.net.ssl.SSLHandshakeException:?com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException:?Could?not?validate?certificate?signature.??
這個就是服務(wù)器配置了自定義的https證書,需要在移動端配置證書校驗或者信任所有證書贷腕,也就是我寫這篇的原因背镇。
javax.net.ssl.SSLHandshakeException: Handshake failed
這個異常我覺得還是服務(wù)器的配置問題,有可能會面臨ios能訪問android不能訪問的囧境泽裳。讀者可以參考下面2篇文章
https://blog.csdn.net/OONullPointerAlex/article/details/49788265
https://blog.csdn.net/taiyangdao/article/details/54707184
2.報錯 javax.net.ssl.SSLPeerUnverifiedException: Hostname domain.com not verified
錯誤原因是驗證證書時發(fā)現(xiàn)真正請求和服務(wù)器的證書域名不一致 例如查看服務(wù)器證書瞒斩,發(fā)現(xiàn)其中的域名為 CN=www.onlinehome-server.com? 而我們的真正請求的域名為 74.208.145.100
或者服務(wù)端https的證書沒有過審,但是本身用的自定義的證書诡壁,解決方案如下
想要深入了解的老鐵們可以去看看SSL安全協(xié)議济瓢,這樣寫實際上降低了https的安全性了,不過證書不過審只能這樣了妹卿,不然 重新生成服務(wù)器的證書,用真實的域名信息蔑鹦。
3.javax.net.ssl.SSLPeerUnverifiedException
原因:SSL鏈接時主機名驗證失敗 這個我暫時沒遇到夺克,解決方案當然是重新生成證書。
4.java.security.cert.CertPathValidatorException: Trust anchor for certificatio?
這個我解決的比較奇葩 好像是后臺沒配置好證書嚎朽,老鐵們遇到這個的時候可以找找后臺大兄弟的麻煩铺纽。