Android or java https ssl exception
来源:互联网 发布:文武学校 知乎 编辑:程序博客网 时间:2024/06/06 09:02
该文出自:http://www.trinea.cn/android/android-java-https-ssl-exception-2/
详细分析Android及Java中访问https请求exception(SSLHandshakeException, SSLPeerUnverifiedException)的原因及解决方法。
1、现象
用Android(或Java)测试程序访问下面两个链接。
https链接一:web服务器为jetty,后台语言为java。
https链接二:web服务器为nginx,后台语言为php。
链接一能正常访问,访问链接二报异常,且用HttpURLConnection和apache的HttpClient两种不同的api访问异常信息不同,具体如下:
(1) 用HttpURLConnection访问,测试代码如下:
异常信息为:
(2) 用apache的HttpClient访问,测试代码如下:
异常信息为:
2、原因分析
需要快速寻求答案的可直接看第3部分 解决方式,这部分详细分析原因。
google发现stackoverflow上不少人反应,twitter和新浪微博的api也会报这个异常,不少人反映客户端需要导入证书,其实大可不必,如果要导证书的话,用户不得哭了。。
从上面的情况可以看出,用jetty做为容器是能正常访问的,只是当容器为nginx时才会异常。
配合后台开发调试了很久,开始以为是cipher suite的问题,为此特地把
ssl_ciphers EDH-RSA-DES-CBC3-SHA;
加入了nginx的配置中,后来发现依然无效。stackoverflow发现,如下代码是能正常访问上面异常的https url
可以看出其中与之前的HttpsURLConnection测试代码主要的不同就是加入了
和
表示相信所有证书,并且所有host name验证返回true,这样就能定位到之前的异常是证书验证不通过的问题了。
在上面checkServerTrusted函数中添加断点,查看X509Certificate[] chain的值,即证书信息,发现访问两个不同链接X509Certificate[] chain值有所区别,nginx传过来证书信息缺少了startssl 的ca证书,证书如下:
至此原因大白:
android的证书库里已经带了startssl ca证书,而nginx默认不带startssl ca证书,这样android端访问nginx为容器的https url校验就会失败,jetty默认带startssl ca证书,所以正常。
PS:后来对windows和mac下java访问https也做了测试,发现mac上的jdk缺省不带startssl ca证书所以能访问通过,而加上startssl ca证书后同android一样访问不通过。而windows上的jdk缺省带startssl ca证书同android一样访问失败。
3、解决方式
上面的分析中已经介绍了一种解决方法即客户端相信所有证书,不过这种方式只是规避了问题,同时也给客户端带来了风险,比较合适的解决方式是为nginx添加startssl ca证书,添加方法如下:
First, use the StartSSL™ Control Panel to create a private key and certificate and transfer them to your server. Then execute the following steps (if you use a class 2 certificate replace class1 by class2 in the instructions below):
- Decrypt the private key by using the password you entered when you created your key:
openssl rsa -in ssl.key -out /etc/nginx/conf/ssl.key
Alternatively you can also use the Tool Box decryption tool of your StartSSL™ account.
- Protect your key from prying eyes:
chmod 600 /etc/nginx/conf/ssl.key
- Fetch the Root CA and Class 1 Intermediate Server CA certificates:
wget http://www.startssl.com/certs/ca.pem
wget http://www.startssl.com/certs/sub.class1.server.ca.pem
- Create a unified certificate from your certificate and the CA certificates:
cat ssl.crt sub.class1.server.ca.pem ca.pem > /etc/nginx/conf/ssl-unified.crt
- Configure your nginx server to use the new key and certificate (in the global settings or a server section):
ssl on;
ssl_certificate /etc/nginx/conf/ssl-unified.crt;
ssl_certificate_key /etc/nginx/conf/ssl.key;
- Tell nginx to reload its configuration:
killall -HUP nginx
也可以直接访问install startssl on nginx.
- Android or java https ssl exception
- volley Android or java https ssl exception
- Android or java https ssl exception
- android ssl、https验证
- android https+ ssl支持
- java SSL https 资料
- android ssl验证、https验证
- android ssl验证、https验证
- android ssl验证、https验证
- Android SSL验证 Https验证
- Android HTTPS SSL双向验证
- Android HTTPS SSL双向验证
- Android HTTPS SSL双向验证
- 关于Java处理Https SSL
- Android Tomcal SSL Https 单向篇
- Android:Security with HTTPS and SSL
- Android上面HTTPS的SSL连接认证
- Android Webview https ssl 空白页解决方法
- php接口开发入门(一)--Mac10.10下环境搭建
- cocos studio设计界面,在代码中寻找按钮,设置监听函数等
- 15个对开发人员最佳的Chrome扩展插件
- SQLyog 导入外部.sql数据库文件 导入没有反应解决
- ios 定时器timer
- Android or java https ssl exception
- A. Arrays------(Codeforces Round #317 [AimFund Thanks-Round] (Div. 2))
- vector容器与iterator迭代器
- NYOJ311 完全背包
- 在Activity或fragment中响应ListView内部控件的点击事件
- RelativeLayout常用属性介绍
- IO操作
- 验证码倒计时函数
- php中文正则