android https安全连接
如果不需要验证服务器端证书,直接照这里做
- public class Demo extends Activity {
- /** Called when the activity is first created. */
- private TextView text;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- text = (TextView)findViewById(R.id.text);
- GetHttps();
- }
- private void GetHttps(){
- String https = " https://800wen.com/";
- try{
- SSLContext sc = SSLContext.getInstance("TLS");
- sc.init(null, new TrustManager[]{new MyTrustManager()}, new SecureRandom());
- HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
- HttpsURLConnection.setDefaultHostnameVerifier(new MyHostnameVerifier());
- HttpsURLConnection conn = (HttpsURLConnection)new URL(https).openConnection();
- conn.setDoOutput(true);
- conn.setDoInput(true);
- conn.connect();
- BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
- StringBuffer sb = new StringBuffer();
- String line;
- while ((line = br.readLine()) != null)
- sb.append(line);
- text.setText(sb.toString());
- }catch(Exception e){
- Log.e(this.getClass().getName(), e.getMessage());
- }
- }
- private class MyHostnameVerifier implements HostnameVerifier{
- @Override
- public boolean verify(String hostname, SSLSession session) {
- // TODO Auto-generated method stub
- return true;
- }
- }
- private class MyTrustManager implements X509TrustManager{
- @Override
- public void checkClientTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- // TODO Auto-generated method stub
- }
- @Override
- public void checkServerTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- // TODO Auto-generated method stub
- }
- @Override
- public X509Certificate[] getAcceptedIssuers() {
- // TODO Auto-generated method stub
- return null;
- }
- }
- }
如果需要验证服务器端证书(这样能够防钓鱼),我是这样做的,还有些问题问大牛:
a. 导出公钥。在浏览器上用https访问tomcat,查看其证书,并另存为一个文件(存成了X.509格式:xxxx.cer)
b. 导入公钥。把xxxx.cer放在Android的assets文件夹中,以方便在运行时通过代码读取此证书,留了两个问题给大牛:
- AssetManager am = context.getAssets();
- InputStream ins = am.open("robusoft.cer");
- try {
- //读取证书
- CertificateFactory cerFactory = CertificateFactory.getInstance("X.509"); //问1
- Certificate cer = cerFactory.generateCertificate(ins);
- //创建一个证书库,并将证书导入证书库
- KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC"); //问2
- keyStore.load(null, null);
- keyStore.setCertificateEntry("trust", cer);
- return keyStore;
- } finally {
- ins.close();
- }
- //把咱的证书库作为信任证书库
- SSLSocketFactory socketFactory = new SSLSocketFactory(keystore);
- Scheme sch = new Scheme("https", socketFactory, 443);
- //完工
- HttpClient mHttpClient = new DefaultHttpClient();
- mHttpClient.getConnectionManager().getSchemeRegistry().register(sch);
问1:这里用"PKCS12"不行
答1:PKCS12和JKS是keystore的type,不是Certificate的type,所以X.509不能用PKCS12代替
问2:这里用"JKS"不行。
答2:android平台上支持的keystore type好像只有PKCS12,不支持JKS,所以不能用JKS代替在PKCS12,不过在windows平台上是可以代替的
----------------------------------------------分割线-------------------------------------------------------------------------
1。数据通信时加密,不同平台加密后的结果不同,用的库不同吧(进行相应的修改比较麻烦)
2。采用https,系统自动做好了,简单一些
https与http的通信,在我看来主要的区别在于https多了一个安全验证机制,而Android采用的是X509验证,首先我们需要这重写X509类,建立我们的验证规则、、不过对于特定的项目,我们一般都是无条件信任服务端的,因此我们可以对任何证书都无条件信任(其实本质上我们只是信任了特定url的证书,为了偷懒,才那么选择的)/**
- * 信任所有主机-对于任何证书都不做检查
- */
- class MytmArray implements X509TrustManager {
- public X509Certificate[] getAcceptedIssuers() {
- // return null;
- return new X509Certificate[] {};
- }
- @Override
- public void checkClientTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- // TODO Auto-generated method stub
- }
- @Override
- public void checkServerTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- // TODO Auto-generated method stub
- // System.out.println("cert: " + chain[0].toString() + ", authType: "
- // + authType);
- }
- };
- * 信任所有主机-对于任何证书都不做检查
- */
- class MytmArray implements X509TrustManager {
- public X509Certificate[] getAcceptedIssuers() {
- // return null;
- return new X509Certificate[] {};
- }
- @Override
- public void checkClientTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- // TODO Auto-generated method stub
- }
- @Override
- public void checkServerTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- // TODO Auto-generated method stub
- // System.out.println("cert: " + chain[0].toString() + ", authType: "
- // + authType);
- }
- };
好了,我们写好了信任规则,接下载就要创建一个主机的信任列表
- static TrustManager[] xtmArray = new MytmArray[] { new MytmArray() };
- /**
- * 信任所有主机-对于任何证书都不做检查
- */
- private static void trustAllHosts() {
- // Create a trust manager that does not validate certificate chains
- // Android 采用X509的证书信息机制
- // Install the all-trusting trust manager
- try {
- SSLContext sc = SSLContext.getInstance("TLS");
- sc.init(null, xtmArray, new java.security.SecureRandom());
- HttpsURLConnection
- .setDefaultSSLSocketFactory(sc.getSocketFactory());
- // HttpsURLConnection.setDefaultHostnameVerifier(DO_NOT_VERIFY);//
- // 不进行主机名确认
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
- @Override
- public boolean verify(String hostname, SSLSession session) {
- // TODO Auto-generated method stub
- // System.out.println("Warning: URL Host: " + hostname + " vs. "
- // + session.getPeerHost());
- return true;
- }
- };
- static TrustManager[] xtmArray = new MytmArray[] { new MytmArray() };
- /**
- * 信任所有主机-对于任何证书都不做检查
- */
- private static void trustAllHosts() {
- // Create a trust manager that does not validate certificate chains
- // Android 采用X509的证书信息机制
- // Install the all-trusting trust manager
- try {
- SSLContext sc = SSLContext.getInstance("TLS");
- sc.init(null, xtmArray, new java.security.SecureRandom());
- HttpsURLConnection
- .setDefaultSSLSocketFactory(sc.getSocketFactory());
- // HttpsURLConnection.setDefaultHostnameVerifier(DO_NOT_VERIFY);//
- // 不进行主机名确认
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
- @Override
- public boolean verify(String hostname, SSLSession session) {
- // TODO Auto-generated method stub
- // System.out.println("Warning: URL Host: " + hostname + " vs. "
- // + session.getPeerHost());
- return true;
- }
- };
上面的都是https通信需要做的几个基本要求,接下载我们要做的就是https的使用啦下面就以get和post为例进行说明,中间还涉及到cookie的使用
- String httpUrl="XXXXX"
- String result = "";
- HttpURLConnection http = null;
- URL url;
- try {
- url = new URL(httpUrl);
- // 判断是http请求还是https请求
- if (url.getProtocol().toLowerCase().equals("https")) {
- trustAllHosts();
- http = (HttpsURLConnection) url.openConnection();
- ((HttpsURLConnection) http).setHostnameVerifier(DO_NOT_VERIFY);// 不进行主机名确认
- } else {
- http = (HttpURLConnection) url.openConnection();
- }
- http.setConnectTimeout(10000);// 设置超时时间
- http.setReadTimeout(50000);
- http.setRequestMethod("GET");// 设置请求类型为
- http.setDoInput(true);
- http.setRequestProperty("Content-Type", "text/xml");
- //http.getResponseCode());http或https返回状态200还是403
- BufferedReader in = null;
- if (obj.getHttpStatus() == 200) {
- getCookie(http);
- in = new BufferedReader(new InputStreamReader(
- http.getInputStream()));
- } else
- in = new BufferedReader(new InputStreamReader(
- http.getErrorStream()));
- result = in.readLine();
- Log.i("result", result);
- in.close();
- http.disconnect();
- String httpUrl="XXXXX"
- String result = "";
- HttpURLConnection http = null;
- URL url;
- try {
- url = new URL(httpUrl);
- // 判断是http请求还是https请求
- if (url.getProtocol().toLowerCase().equals("https")) {
- trustAllHosts();
- http = (HttpsURLConnection) url.openConnection();
- ((HttpsURLConnection) http).setHostnameVerifier(DO_NOT_VERIFY);// 不进行主机名确认
- } else {
- http = (HttpURLConnection) url.openConnection();
- }
- http.setConnectTimeout(10000);// 设置超时时间
- http.setReadTimeout(50000);
- http.setRequestMethod("GET");// 设置请求类型为
- http.setDoInput(true);
- http.setRequestProperty("Content-Type", "text/xml");
- //http.getResponseCode());http或https返回状态200还是403
- BufferedReader in = null;
- if (obj.getHttpStatus() == 200) {
- getCookie(http);
- in = new BufferedReader(new InputStreamReader(
- http.getInputStream()));
- } else
- in = new BufferedReader(new InputStreamReader(
- http.getErrorStream()));
- result = in.readLine();
- Log.i("result", result);
- in.close();
- http.disconnect();
https或http的get请求写好了,哦中间涉及到了一个getCookie的方法,如下:
- /** 得到cookie */
- private static void getCookie(HttpURLConnection http) {
- String cookieVal = null;
- String key = null;
- DataDefine.mCookieStore = "";
- for (int i = 1; (key = http.getHeaderFieldKey(i)) != null; i++) {
- if (key.equalsIgnoreCase("set-cookie")) {
- cookieVal = http.getHeaderField(i);
- cookieVal = cookieVal.substring(0, cookieVal.indexOf(";"));
- DataDefine.mCookieStore = DataDefine.mCookieStore + cookieVal
- + ";";
- }
- }
- }
- /** 得到cookie */
- private static void getCookie(HttpURLConnection http) {
- String cookieVal = null;
- String key = null;
- DataDefine.mCookieStore = "";
- for (int i = 1; (key = http.getHeaderFieldKey(i)) != null; i++) {
- if (key.equalsIgnoreCase("set-cookie")) {
- cookieVal = http.getHeaderField(i);
- cookieVal = cookieVal.substring(0, cookieVal.indexOf(";"));
- DataDefine.mCookieStore = DataDefine.mCookieStore + cookieVal
- + ";";
- }
- }
- }
public static Query HttpQueryReturnClass(String httpUrl, String base64) {
- String result = "";
- Log.i("控制", httpUrl);
- Query obj = new Query();
- HttpURLConnection http = null;
- URL url;
- try {
- url = new URL(httpUrl);
- // 判断是http请求还是https请求
- if (url.getProtocol().toLowerCase().equals("https")) {
- trustAllHosts();
- http = (HttpsURLConnection) url.openConnection();
- ((HttpsURLConnection) http).setHostnameVerifier(DO_NOT_VERIFY);// 不进行主机名确认
- } else {
- http = (HttpURLConnection) url.openConnection();
- }
- http.setConnectTimeout(10000);// 设置超时时间
- http.setReadTimeout(50000);
- http.setRequestMethod("POST");// 设置请求类型为post
- http.setDoInput(true);
- http.setDoOutput(true);
- http.setRequestProperty("Content-Type", "text/xml");
- http.setRequestProperty("Cookie", DataDefine.mCookieStore);
- DataOutputStream out = new DataOutputStream(http.getOutputStream());
- out.writeBytes(base64);
- out.flush();
- out.close();
- obj.setHttpStatus(http.getResponseCode());// 设置http返回状态200还是403
- BufferedReader in = null;
- if (obj.getHttpStatus() == 200) {
- getCookie(http);
- in = new BufferedReader(new InputStreamReader(
- http.getInputStream()));
- } else
- in = new BufferedReader(new InputStreamReader(
- http.getErrorStream()));
- result = in.readLine();// 得到返回结果
- in.close();
- http.disconnect();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- String result = "";
- Log.i("控制", httpUrl);
- Query obj = new Query();
- HttpURLConnection http = null;
- URL url;
- try {
- url = new URL(httpUrl);
- // 判断是http请求还是https请求
- if (url.getProtocol().toLowerCase().equals("https")) {
- trustAllHosts();
- http = (HttpsURLConnection) url.openConnection();
- ((HttpsURLConnection) http).setHostnameVerifier(DO_NOT_VERIFY);// 不进行主机名确认
- } else {
- http = (HttpURLConnection) url.openConnection();
- }
- http.setConnectTimeout(10000);// 设置超时时间
- http.setReadTimeout(50000);
- http.setRequestMethod("POST");// 设置请求类型为post
- http.setDoInput(true);
- http.setDoOutput(true);
- http.setRequestProperty("Content-Type", "text/xml");
- http.setRequestProperty("Cookie", DataDefine.mCookieStore);
- DataOutputStream out = new DataOutputStream(http.getOutputStream());
- out.writeBytes(base64);
- out.flush();
- out.close();
- obj.setHttpStatus(http.getResponseCode());// 设置http返回状态200还是403
- BufferedReader in = null;
- if (obj.getHttpStatus() == 200) {
- getCookie(http);
- in = new BufferedReader(new InputStreamReader(
- http.getInputStream()));
- } else
- in = new BufferedReader(new InputStreamReader(
- http.getErrorStream()));
- result = in.readLine();// 得到返回结果
- in.close();
- http.disconnect();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
这里面的base64是我经过base64加密过以后的数据
android https安全连接的更多相关文章
- 用代码实现断开Android手机USB连接【转】
本文转载自:https://blog.csdn.net/phoebe_2012/article/details/47025309 用代码实现断开Android手机USB连接 ...
- [RN] Android 设备adb连接后unauthorized解决方法
Android 设备adb连接后unauthorized解决方法 安卓设备usb或者adbwireless连接后输入adb device后都是未授权状态 相信很多同学都会遇到这种情况,除了一直重复开关 ...
- 如何使用charles对Android Https进行抓包
Charles.png charles是一款在Mac下常用的截取网络封包工具,对Android Http进行抓包,只要对手机设置代理即可,但对Android Https进行抓包还是破费一些功夫,网 ...
- 71.Android之长连接实现
转载:http://blog.csdn.net/qq_23547831/article/details/51690047 本文中我们将讲解一下App的长连接实现.一般而言长连接已经是App的标配了,推 ...
- Android平台上长连接的实现
Android 平台上长连接的实现 为了不让 NAT 表失效,我们需要定时的发心跳,以刷新 NAT 表项,避免被淘汰. Android 上定时运行任务常用的方法有2种,一种方法用 Timer,另一种是 ...
- [转]Mac OS X 下部分Android手机无法连接adb问题之解决方案
时至当今,Android山寨手机厂商已如此之多,能修改和个性化定制Android OS的能人已是多如牛毛,有的牛人修改Android系统只会影响所修改的点,不会影响其它,然后还有的就不多说了,总之做的 ...
- 小米2及其他Android手机无法连接mac解决方案
一般的android连接mac 很方便不用安装驱动就可以啦,可是不知道为什么二般情况下有的android手机(小米2,华为等)就是连接不上,下来就说说二般情况下如何连接. 1.关于本机-->更多 ...
- Android Https双向认证 + GRPC
keywords:android https 双向认证android GRPC https 双向认证 ManagedChannel channel = OkHttpChannelBuilder.for ...
- Android蓝牙A2DP连接实现
代码地址如下:http://www.demodashi.com/demo/14624.html 开发环境: 开发工具:Androidstudio 适配机型:honor8(Android6.0), 坚果 ...
随机推荐
- mysql进阶(二十七)数据库索引原理
mysql进阶(二十七)数据库索引原理 前言 本文主要是阐述MySQL索引机制,主要是说明存储引擎Innodb. 第一部分主要从数据结构及算法理论层面讨论MySQL数据库索引的数理基础. ...
- xlsx批量转为utf8的csv
xlsx批量转为utf8的csv(金庆的专栏)策划的配置表为 xlsx 表格,可以有注释,公式.服务器和客户端使用的配置文件需要转成 csv 文件.使用 WPS 另存无法批量转换,并且结果不是utf8 ...
- T-SQL动态查询(4)——动态SQL
接上文:T-SQL动态查询(3)--静态SQL 前言: 前面说了很多关于动态查询的内容,本文将介绍使用动态SQL解决动态查询的一些方法. 为什么使用动态SQL: 在很多项目中,动态SQL被广泛使用甚至 ...
- #VSTS日志# Xamarin构建支持和一大波更新
距离上次更新#VSTS日志#已经有将近3个月的时间了,赶上最近Xamarin开源免费的消息,VSTS也推出了更多跨平台的支持和许多其他功能.这里列出一些小编觉得比较重要. 1. Xamarin 构建模 ...
- iOS 10 推送全解析,注意事项
本文旨在对 iOS 推送进行一个完整的剖析,如果你之前对推送一无所知,那么在你认真地阅读了全文后必将变成一个推送老手,你将会对其中的各种细节和原理有充分的理解.以下是 pikacode 使用 iOS ...
- android最新更新方法
使用SDK Manager更新时出现问题Failed to fetch URL https://dl-ssl.google.com/android/repository/repository-6.xm ...
- 运用 三种 原生 谷歌 阿里 解析和生成json
三种类生成JSON数据方法 JSON(原生): 第一种 JSONStringer和JSONObject区别在于添加对象时是按顺序添加的比如说 JSONStringer 添加 a:1 b:2 c:3那么 ...
- 【java集合框架源码剖析系列】java源码剖析之HashSet
注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本.本博客将从源码角度带领大家学习关于HashSet的知识. 一HashSet的定义: public class HashSet&l ...
- 应用UUID简化设计
应用UUID简化设计(金庆的专栏)UUID(Universally Unique Identifier) 保证每次生成的都是唯一的,不同机器生成UUID也能保证唯一.网游中使用UUID可以避免全局的I ...
- 《java入门第一季》之HashSet存储自定义对象问题以及注意事项
上一篇http://blog.csdn.net/qq_32059827/article/details/51578158 写到存储字符串类型的时候出现了无序,而且这个无序不是随机那种无序,它是有一定存 ...