android中使用https是否对服务证书合法性校验的新的体会
package com.cetcs.logreport.utils; import android.content.Context; import org.apache.http.conn.ssl.SSLSocketFactory; import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SignatureException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate; import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager; /**
*
* 解析服务器证书的类,对服务器端的证书serv.crt进行解析,其中server.crt文件是使用
* openssl生成的自签名的证书
* */
public class SSLVerifyLogServerCrtSocketFactory extends SSLSocketFactory { private static final String TAG = "SSLTrustAllSocketFactory";
private SSLContext mCtx;
private Context context; public SSLVerifyLogServerCrtSocketFactory(String crtName, KeyStore truststore, Context context)
throws Throwable {
super(truststore);
this.context = context;
try {
InputStream certInputStream = new BufferedInputStream(context.getAssets().open(crtName));
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
final X509Certificate serverCertificate = (X509Certificate) certificateFactory.generateCertificate(certInputStream);
mCtx = SSLContext.getInstance("TLS");
mCtx.init(null, new TrustManager[]{new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String authType) throws CertificateException {
if(x509Certificates == null){
throw new IllegalArgumentException("checkServerTrusted x509Certificates is null ");
}
if(x509Certificates.length < 0){
throw new IllegalArgumentException("checkServerTrusted x509Certificates is null ");
} for(X509Certificate cert :x509Certificates){
cert.checkValidity();
try {
cert.verify(serverCertificate.getPublicKey());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (SignatureException e) {
e.printStackTrace();
}
} } @Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}},
null);
} catch (Exception ex) {
}
} @Override
public Socket createSocket(Socket socket, String host,
int port, boolean autoClose)
throws IOException, UnknownHostException {
return mCtx.getSocketFactory().createSocket(socket, host, port, autoClose);
} @Override
public Socket createSocket() throws IOException {
return mCtx.getSocketFactory().createSocket();
} //第一个参数是服务器证书的名字例如:server.crt,第二个参数是应用的上下文
public static SSLSocketFactory getSocketFactory( String crtName,Context context) {
try {
if(crtName == null || "".equalsIgnoreCase(crtName)){
throw new IllegalArgumentException(" getSocketFactory crtName is null");
}
if(context == null){
throw new IllegalArgumentException(" getSocketFactory context is null");
}
InputStream certInputStream = new BufferedInputStream(context.getAssets().open(crtName));
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
X509Certificate serverCertificate = (X509Certificate) certificateFactory.generateCertificate(certInputStream);
//生成一个保护服务器证书的keystore
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
String alias = serverCertificate.getSubjectX500Principal().getName();
keyStore.setCertificateEntry(alias, serverCertificate); //生成SSLSocketFactory
SSLSocketFactory factory = new SSLVerifyLogServerCrtSocketFactory(crtName,keyStore,context);
return factory;
} catch (Throwable e) {
e.printStackTrace();
}
return null;
} }
需求使用:实现客户端对服务器的校验,需要认证服务器证书的合法性,当https在握手的协议中返回给客户端的证书应该和保存在客户端本地的证书解析出来的域名应该一样,说明服务器返回的证书给保证在本地的证书是一样的,说明服务器是合法的
try {
String crtName = "server.crt";
SSLSocketFactory sf = SSLVerifyLogServerCrtSocketFactory.getSocketFactory(crtName, mContext);
//对主机的有效域名进行严格校验
sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);return new DefaultHttpClient(ccm, params);
其中server.crt就是保存在手机app 例如assert目录下的证书,是app本地保证的证书,这个证书必须和配置到后台例如tomacat服务器中的证书是一模一样,这里为了客户端验证服务器证书的合法性,在手机app客户端保存了一个证书
mContext是activity或者context对应的手机的上下文,如果这里客户端和服务器在建立https的过程中,如果服务器返回给客户端的证书的域名和app本地保存的证书解析出来的域名是一样的,说明服务器是合法的。 如果客户端在和服务器建立https协议的时候,不对服务器的合法性做校验,信任所有的服务器
package com.cetcs.logreport.utils; /**
* Created by wei.yuan on 2016/8/2.
*
* 该类主要是用于对服务器证书的单项验证
*/ import org.apache.http.conn.ssl.SSLSocketFactory; import java.io.IOException;
import java.lang.reflect.Field;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate; import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager; public class SSLSocketFactoryEx extends SSLSocketFactory { SSLContext sslContext = SSLContext.getInstance("TLS"); public SSLSocketFactoryEx(KeyStore truststore) throws NoSuchAlgorithmException,
KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super(truststore);
// set up a TrustManager that trusts everything
TrustManager tm = new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() {
//return new X509Certificate[]{};
return null;
} @Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
// TODO Auto-generated method stub } @Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// TODO Auto-generated method stub }
}; sslContext.init(null, new TrustManager[] { tm }, new java.security.SecureRandom());
} @Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
throws IOException, UnknownHostException {
injectHostname(socket, host);
return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
} @Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
} private void injectHostname(Socket socket, String host) {
try {
Field field = InetAddress.class.getDeclaredField("hostName");
field.setAccessible(true);
field.set(socket.getInetAddress(), host);
} catch (Exception ignored) {
}
}
}
使用技巧:
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null); SSLSocketFactory sf = new SSLSocketFactoryEx(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
这样大体就是一个使用心得
android中使用https是否对服务证书合法性校验的新的体会的更多相关文章
- Android中使用GoogleMap的地理位置服务
写在前面:android中使用地理位置功能,可以借助Google给我们提供的框架,要是有地理位置功能,你需要引用Google Play Services,请在sdk manager中下载.如果你还要使 ...
- Android中获取正在运行的服务-------ActivityManager.RunningServiceInfo的使用
关于PackageManager和ActivityManager的使用 ,自己也写了一些DEMO 了,基本上写的线路参考了Settings模块下的 应用程序,大家如果真正的有所兴趣,建议大家看看源码, ...
- Android中Chronometer 计时器和震动服务控件
Chronometer 计时器控件 首先在布局文件中添加chronometer控件:然后在mainActivity中获取到该控件 4 然后通过Button时间监听器中开启计时操作 5 chronome ...
- https请求之绕过证书安全校验工具类(原)
package com.isoftstone.core.util; import java.io.BufferedReader; import java.io.ByteArrayOutputStrea ...
- https请求之绕过证书安全校验相关配置
需在weblogic服务器上配置内存溢出的地方加入一行配置: -DUseSunHttpHandler=true 注:空格隔开 然后调用工具类:https://www.cnblogs.com/ ...
- HTTPS 原理浅析及其在 Android 中的使用
作者:曹丰斌 本文首先分析HTTP协议在安全性上的不足,进而阐述HTTPS实现安全通信的关键技术点和原理.然后通过抓包分析HTTPS协议的握手以及通信过程.最后总结一下自己在开发过程中遇到的HTT ...
- Android中Service和Activity之间的通信
启动Service并传递数据进去: Android中通过Intent来启动服务会传递一个Intent过去. 可以在Intent中通过putExtra()携带数据 Intent startIntent ...
- android中开启线程
其实Android启动线程和JAVA一样有两种方式,一种是直接Thread类的start方法,也就是一般写一个自己的类来继承Thread类.另外一种方式其实和这个差不多啊! 那就是Runnable接口 ...
- Https通信原理及Android中实用总结
一.背景 Http俨然已经成为互联网上最广泛使用的应用层协议,随着应用形态的不断演进,传统的Http在安全性上开始面临挑战,Http主要安全问题体现在: 1,信息内容透明传输. 2,通信对方的身份不可 ...
随机推荐
- excel操作数据实用技能
写代码写习惯了,在做数据预处理时也总是习惯性地用python.pandas来做处理,但其实有时候根本不需要写代码,用excel也能达到目的,甚至比写代码快很多,写代码要半天,excel只要几秒钟.下面 ...
- 关于oauth安全
白话认证流程 A)用户打开客户端以后,客户端要求用户给予授权.(比如说你登陆淘宝,通过QQ这个第三方来登录时,这个时候淘宝将你引导至QQ的认证服务器) B)用户同意给客户端授权.(这个时候在你手机上弹 ...
- 通过jquery实现tab切换
//css代码 *{ margin: 0; padding: 0; } #box{ margin: 0 auto; width: 800px; border: 5px solid #000000; o ...
- 跨域解决方案 - JSONP
目录 1. 定义 2. JSONP 解决跨域 3. 应用场景 4. 代码演示 1. 定义 在HTML 中, script 标签有两个个性质: script 标签可以不受同源策略的限制去访问服务器资源, ...
- JAVASE(八) 数组: 一维数组、二维数组、动态数组、静态数组
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 1.一维数组 1.1 数组的声明和初始化声明方式: String str[]; //不建议使用 Stri ...
- Java实现 蓝桥杯 算法提高 快乐司机
算法提高 快乐司机 时间限制:1.0s 内存限制:256.0MB 问题描述 "嘟嘟嘟嘟嘟嘟 喇叭响 我是汽车小司机 我是小司机 我为祖国运输忙 运输忙" 这是儿歌"快乐的 ...
- Java实现 LeetCode 300 最长上升子序列
300. 最长上升子序列 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,10 ...
- Java实现 蓝桥杯VIP 算法训练 摆动序列
问题描述 如果一个序列满足下面的性质,我们就将它称为摆动序列: 1. 序列中的所有数都是不大于k的正整数: 2. 序列中至少有两个数. 3. 序列中的数两两不相等: 4. 如果第i – 1个数比第i ...
- Android中如何使用Listview
第一步 首先在xml文件中声明一个List View控件,并且标明id (这一步其实不用说,怕自学Android的小白不懂,就好比当初的我,哈哈) <?xml version="1.0 ...
- Java实现蓝桥杯二项式的系数规律
二项式的系数规律,我国数学家很早就发现了. 如[图1.png],我国南宋数学家杨辉1261年所著的<详解九章算法>一书里就出现了. 其排列规律: 1 1 1 2 1 3 3 1 4 6 4 ...