最近為了網(wǎng)絡(luò)安全,項(xiàng)目決定把以前的http請求全部換成https,本來用公司級生成的正式證書什么問題的不會有,也不用考慮新增代碼。不過貌似證書很貴,所有采用了自己生成證書,那么事就這么來了。
先向服務(wù)器大哥討要證書.cer文件,可以放在raw或者assets文件夾下面。用下面的方法獲取證書數(shù)據(jù)
在application類中,配置okhttpclient之前先讀取信息
添加證書
主要會用到下面這個(gè)方法
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;
}
處理這個(gè)問題的時(shí)候發(fā)現(xiàn)可能還會碰到更復(fù)雜更安全的方式,如雙向證書認(rèn)證等,給大家放個(gè)鏈接,感覺這個(gè)介紹的更加具體仔細(xì)
http://blog.csdn.net/quincyjiang/article/details/76273446
運(yùn)行報(bào)錯的幾個(gè)異常處理
1.報(bào)錯javax.net.ssl.SSLHandshakeException,這個(gè)異常主要會出現(xiàn)兩種情況
javax.net.ssl.SSLHandshakeException:?com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException:?Could?not?validate?certificate?signature.??
這個(gè)就是服務(wù)器配置了自定義的https證書,需要在移動端配置證書校驗(yàn)或者信任所有證書,也就是我寫這篇的原因。
javax.net.ssl.SSLHandshakeException: Handshake failed
這個(gè)異常我覺得還是服務(wù)器的配置問題,有可能會面臨ios能訪問android不能訪問的囧境。讀者可以參考下面2篇文章
https://blog.csdn.net/OONullPointerAlex/article/details/49788265
https://blog.csdn.net/taiyangdao/article/details/54707184
2.報(bào)錯 javax.net.ssl.SSLPeerUnverifiedException: Hostname domain.com not verified
錯誤原因是驗(yàn)證證書時(shí)發(fā)現(xiàn)真正請求和服務(wù)器的證書域名不一致 例如查看服務(wù)器證書,發(fā)現(xiàn)其中的域名為 CN=www.onlinehome-server.com? 而我們的真正請求的域名為 74.208.145.100
或者服務(wù)端https的證書沒有過審,但是本身用的自定義的證書,解決方案如下
想要深入了解的老鐵們可以去看看SSL安全協(xié)議,這樣寫實(shí)際上降低了https的安全性了,不過證書不過審只能這樣了,不然 重新生成服務(wù)器的證書,用真實(shí)的域名信息。
3.javax.net.ssl.SSLPeerUnverifiedException
原因:SSL鏈接時(shí)主機(jī)名驗(yàn)證失敗 這個(gè)我暫時(shí)沒遇到,解決方案當(dāng)然是重新生成證書。
4.java.security.cert.CertPathValidatorException: Trust anchor for certificatio?
這個(gè)我解決的比較奇葩 好像是后臺沒配置好證書,老鐵們遇到這個(gè)的時(shí)候可以找找后臺大兄弟的麻煩。