OTA服务器和android客户端添加HTTPS协议
2016-11-30 12:15
351 查看
有段时间没总结了,这期间主要学习三个问题:
一是https协议,OTA HTTPS 协议可以工作了。
二是消息推送,推送用的是openfire+asmack方案,目前只能给所有用户广播消息,如果针对不同项目用户,服务器端还需要单独开发插件支持,这个后面继续研究。
三是服务器并发压力测试,测试工具用的是jmeter,这个工具还是很强大的,可以同时模拟成千上万的用户同时访问服务器。
知识点很多,很多还是一知半解的。
一、HTTPS协议
HTTPS 协议主要是为了解决安全问题,在HTTP到TCP层之间加入SSL/TLS层,ssl提供了身份验证和通信加密。
下图是一张双向认证的tcpdump log,可以看出HTTPS协议的基本工作流程。
1. 首先执行基本的TCP三步握手
2. 客户端给服务器发client hello问候语,问候语中包含客户端支持的加密算法,压缩算法,SSL/TLS 版本,随机数
3. 服务器响应问候语,返回server hello问候语,问候语中包含客户端的随机数,确定的通信加密算法。
4.服务器把自己的证书发给客户端,告诉客户端说我这台服务器是合法的,不信可以用CA去校验。此时客户端可以通过CA(CA可以自己生成)去校验
如果合法就继续访问,不合法就提示用户等处理。
5.同时服务器也需要验证客户端是不是合法的,所以它请求客户端提供自己的证书。此时客户端就把证书发给服务器。
6. 如果都双方证书都验证通过,就开始进行加密过程试通信,如果数据解析都没问题,就开始正式传输数据。
二、 服务器端配置
1. 首先通过openssl 生成证书
1).生成私钥:
openssl genrsa -out private/server.key 1024
也可以生成加密的私钥,但是windows 上的wamp和xampp 不支持加密的。
openssl genrsa -des3 -out server.key 1024
2).生成证书请求文件,用这个文件拿去给CA签名。
openssl req -new -key private/server.key -out crl/server.csr
3)用同样的办法生成root.key (自己做的CAkey)和 client.key
4) 用CA key 分别签名server 和 client key
openssl x509 -req -days 3650 -sha1 -extensions v3_ca -signkey root.key -in server.csr -out server.crt
openssl x509 -req -days 3650 -sha1 -extensions v3_ca -signkey root.key -in client.csr -out client.crt
5) 对于xampp ,默认已经打开ssl,但是支持单向认证,所以还需要把httpd-ssl.conf 里的如下项打开,并把root.crt和server.key server.crt证书放到 相应位置
SSLCACertificateFile "conf/otaserver.key/root.crt"
SSLVerifyClient require
SSLVerifyDepth 10
把DocumentRoot和ServerName配置好,可以临时定义一个域名,用于局域网。ServerName 应该和 server证书里面的common name一致。
DocumentRoot "C:/xampp/htdocs/otaserver"
ServerName www.xxx.ota.com:443
6)对于linux系统也差不多配置,这里不再描述。
二 、在浏览器上验证
先用client key生成浏览器用的pfx文件
openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.pfx
把root.crt 安装到浏览器的受信任的证书颁发机构,再点击安装client.pfx。
三、 android 客户端
1. 把client.pfx和root.crt 放到应用assets目录下
2. 添加相关代码
一是https协议,OTA HTTPS 协议可以工作了。
二是消息推送,推送用的是openfire+asmack方案,目前只能给所有用户广播消息,如果针对不同项目用户,服务器端还需要单独开发插件支持,这个后面继续研究。
三是服务器并发压力测试,测试工具用的是jmeter,这个工具还是很强大的,可以同时模拟成千上万的用户同时访问服务器。
知识点很多,很多还是一知半解的。
一、HTTPS协议
HTTPS 协议主要是为了解决安全问题,在HTTP到TCP层之间加入SSL/TLS层,ssl提供了身份验证和通信加密。
下图是一张双向认证的tcpdump log,可以看出HTTPS协议的基本工作流程。
1. 首先执行基本的TCP三步握手
2. 客户端给服务器发client hello问候语,问候语中包含客户端支持的加密算法,压缩算法,SSL/TLS 版本,随机数
3. 服务器响应问候语,返回server hello问候语,问候语中包含客户端的随机数,确定的通信加密算法。
4.服务器把自己的证书发给客户端,告诉客户端说我这台服务器是合法的,不信可以用CA去校验。此时客户端可以通过CA(CA可以自己生成)去校验
如果合法就继续访问,不合法就提示用户等处理。
5.同时服务器也需要验证客户端是不是合法的,所以它请求客户端提供自己的证书。此时客户端就把证书发给服务器。
6. 如果都双方证书都验证通过,就开始进行加密过程试通信,如果数据解析都没问题,就开始正式传输数据。
二、 服务器端配置
1. 首先通过openssl 生成证书
1).生成私钥:
openssl genrsa -out private/server.key 1024
也可以生成加密的私钥,但是windows 上的wamp和xampp 不支持加密的。
openssl genrsa -des3 -out server.key 1024
2).生成证书请求文件,用这个文件拿去给CA签名。
openssl req -new -key private/server.key -out crl/server.csr
3)用同样的办法生成root.key (自己做的CAkey)和 client.key
4) 用CA key 分别签名server 和 client key
openssl x509 -req -days 3650 -sha1 -extensions v3_ca -signkey root.key -in server.csr -out server.crt
openssl x509 -req -days 3650 -sha1 -extensions v3_ca -signkey root.key -in client.csr -out client.crt
5) 对于xampp ,默认已经打开ssl,但是支持单向认证,所以还需要把httpd-ssl.conf 里的如下项打开,并把root.crt和server.key server.crt证书放到 相应位置
SSLCACertificateFile "conf/otaserver.key/root.crt"
SSLVerifyClient require
SSLVerifyDepth 10
把DocumentRoot和ServerName配置好,可以临时定义一个域名,用于局域网。ServerName 应该和 server证书里面的common name一致。
DocumentRoot "C:/xampp/htdocs/otaserver"
ServerName www.xxx.ota.com:443
6)对于linux系统也差不多配置,这里不再描述。
二 、在浏览器上验证
先用client key生成浏览器用的pfx文件
openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.pfx
把root.crt 安装到浏览器的受信任的证书颁发机构,再点击安装client.pfx。
三、 android 客户端
1. 把client.pfx和root.crt 放到应用assets目录下
2. 添加相关代码
private static final String keyStoreFileName ="client.pfx"; private static final String keyStorePassword ="123456"; private static final String trustStoreFileName ="root.crt"; private static final String trustStorePassword ="123456"; try { CertificateFactory cf = CertificateFactory.getInstance("X.509"); InputStream caInput = ct.getResources().getAssets().open(trustStoreFileName); final Certificate ca; try { ca = cf.generateCertificate(caInput); Log.d(TAG, "ca=" + ((X509Certificate) ca).getSubjectDN()); Log.d(TAG, "key=" + ((X509Certificate) ca).getPublicKey()); } finally { caInput.close(); } HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { Log.d(TAG,"verify hostname:"+hostname); return true; } }); KeyManager[] keyManagers = createKeyManagers(ct,keyStoreFileName,keyStorePassword,alias); SSLContext context = SSLContext.getInstance("TLSv1","AndroidOpenSSL"); context.init(keyManagers, new TrustManager[]{ new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { Log.d(TAG,"checkServerTrusted authType:" + authType); for (X509Certificate cert : chain) { // Make sure that it hasn't expired. cert.checkValidity(); Log.d(TAG,"checkServerTrusted cert:" + cert.getPublicKey()); // Verify the certificate's public key chain. try { cert.verify(((X509Certificate) ca).getPublicKey()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); throw new CertificateException(e); } catch (InvalidKeyException e) { e.printStackTrace(); throw new CertificateException(e); } catch (NoSuchProviderException e) { e.printStackTrace(); throw new CertificateException(e); } catch (SignatureException e) { e.printStackTrace(); throw new CertificateException(e); } } } @Override public X509Certificate[] getAcceptedIssuers() { Log.d(TAG,"getAcceptedIssuers"); return new X509Certificate[0]; } } }, null); StringBuilder sb = new StringBuilder(); if(params!=null && !params.isEmpty()){ for(Map.Entry<String, String> entry : params.entrySet()){ sb.append(entry.getKey()).append('=') .append(URLEncoder.encode(entry.getValue(), enc)) .append('&'); } sb.deleteCharAt(sb.length()-1); } Log.d(TAG,"post: send_data:" + sb.toString()); byte[] entitydata = sb.toString().getBytes(); URL url = new URL(path); HttpsURLConnection conn = (HttpsURLConnection)url.openConnection(); conn.setSSLSocketFactory(context.getSocketFactory()); conn.setDefaultHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { //TODO Auto-generated method stub Log.d(TAG,"verify hostname:"+hostname); return true; } }); conn.setRequestMethod("POST"); conn.setConnectTimeout(50 * 1000); conn.setDoOutput(true); //Content-Type: application/x-www-form-urlencoded //Content-Length: 38 conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.setRequestProperty("Content-Length", String.valueOf(entitydata.length)); OutputStream outStream = conn.getOutputStream(); outStream.write(entitydata); outStream.flush(); outStream.close(); if(conn.getResponseCode()==200){ StringBuffer buffer = new StringBuffer(); try { BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8")); String temp; while ((temp = br.readLine()) != null) { buffer.append(temp); buffer.append("\n"); } } catch (Exception e) { e.printStackTrace(); } return buffer.toString(); } } catch (CertificateException e) { e.printStackTrace(); throw new CertificateException(e); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); throw new CertificateException(e); } catch (KeyManagementException e) { e.printStackTrace(); throw new CertificateException(e); } catch (NoSuchProviderException e) { e.printStackTrace(); throw new CertificateException(e); } catch (KeyStoreException e){ e.printStackTrace(); throw new CertificateException(e); }catch(Exception e){ e.printStackTrace(); throw new Exception(e); }
相关文章推荐
- HTTPS-HSTS协议(强制客户端使用HTTPS与服务器创建连接)
- android客户端与服务器交互数据(基于SAOP协议的远程调用标准,通过webservice可以将不同操作系统平台,不同语言,不同技术整合)
- Android仿人人客户端(v5.7.1)——通过HTTPS协议的POST方式获取用户的基本信息
- Android 用Https协议与服务器通信
- Android使用Https协议与Tomcat服务器进行文件上下传,并将上传的文件上传至HDFS
- Android作为服务器通过USB使用Socket协议向PC客户端发送文件
- 网站添加QQ登陆,QQ登录报错:可能是服务器无法请求https协议
- Android客户端使用HttpURLConnection doGet与服务器数据交互简单示例
- netty 3.9.2 UDP协议服务器和客户端DEMO
- Android连接SQLServer详细教程(数据库+服务器+客户端)
- Android客户端与服务器交互中的token
- Android如何通过https协议下载自己的https网站上的文件/apk等
- springboot添加https服务器的方法
- android客户端向服务器发送图片和文字,类似于发微博。能用json格式发送吗?
- c++服务器与android客户端进行文件传输功能的实现
- linux udp协议服务器,客户端socket使用
- Microsoft Lync Server 2010 部署服务器、负载平衡器和客户端使用的端口和协议
- Android:客户端和服务器之间传输数据加密
- 【转】Socket 通信原理(Android客户端和服务器以TCP&&UDP方式互通)
- 通过Android 客户端上传数据到服务器