最近为了网络安全,项目决定把以前的 http 请求全部换成 https, 本来用公司级生成的正式证书什么问题的不会有,也不用考虑新增代码.不过貌似证书很贵,所有采用了自己生成证书,那么事就这么来了.
先向服务器大哥讨要证书. cer 文件, 可以放在 raw 或者 assets 文件夹下面.用下面的方法获取证书数据
在 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;}
处理这个问题的时候发现可能还会碰到更复杂更安全的方式,如双向证书认证等,给大家放个链接,感觉这个介绍的更加具体仔细
http://blog.csdn.net/quincyjiang/article/details/76273446
运行报错的几个异常处理
1. 报错 javax.net.ssl.SSLHandshakeException: Handshake failed
服务器使用自定义的证书,未被信任,客户端需要做相应的配置,也就是我写这篇的原因.
2. 报错 javax.net.ssl.SSLPeerUnverifiedException: Hostname domain.com not verified
错误原因是验证证书时发现真正请求和服务器的证书域名不一致 例如查看服务器证书,发现其中的域名为 CN=www.onlinehome-server.com 而我们的真正请求的域名为 74.208.145.100
或者服务端 https 的证书没有过审,但是本身用的自定义的证书,解决方案如下
忽略 hostname 的验证
想要深入了解的老铁们可以去看看 SSL 安全协议,这样写实际上降低了 https 的安全性了,不过证书不过审只能这样了,不然 重新生成服务器的证书,用真实的域名信息.
3.javax.net.ssl.SSLPeerUnverifiedException
原因:SSL 链接时主机名验证失败 这个我暂时没遇到,解决方案当然是重新生成证书.
4.java.security.cert.CertPathValidatorException: Trust anchor for certificatio
这个我解决的比较奇葩 好像是后台没配置好证书,老铁们遇到这个的时候可以找找后台大兄弟的麻烦.
来源: http://www.jianshu.com/p/9d222c2dcddf