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,通信对方的身份不可 ...
随机推荐
- pandas 小技巧
1.找出某个字段包含某字符串的行: my_df[my_df['col_B'].str.contains('大连') > 0]或者 my_df[my_df['col_B'].apply(lambd ...
- Java实现蓝桥杯 算法提高 八皇后 改
**算法提高 8皇后·改** 时间限制:1.0s 内存限制:256.0MB 提交此题 问题描述 规则同8皇后问题,但是棋盘上每格都有一个数字,要求八皇后所在格子数字之和最大. 输入格式 一个8*8的棋 ...
- Java实现 蓝桥杯VIP 算法训练 数的统计
问题描述 在一个有限的正整数序列中,有些数会多次重复出现在这个序列中. 如序列:3,1,2,1,5,1,2.其中1就出现3次,2出现2次,3出现1 次,5出现1次. 你的任务是对于给定的正整数序列,从 ...
- Java实现 蓝桥杯VIP 算法提高 密码锁
算法提高 题目 2 密码锁 时间限制:1.0s 内存限制:1.0GB 问题描述 你获得了一个据说是古代玛雅人制作的箱子.你非常想打开箱子看看里面有什么东西,但是不幸的是,正如所有故事里一样,神秘的箱子 ...
- java实现迷宫问题
迷宫问题 对于走迷宫,人们提出过很多计算机上的解法.深度优先搜索.广度优先搜索是使用最广的方法.生活中,人们更 愿意使用"紧贴墙壁,靠右行走"的简单规则. 58 下面的代码则采用了 ...
- 运用Navicat for MySQL进行MSSQL数据转移MYSQL
当前不同数据库进行数据转移已经不是一件麻烦事情,特别是有很多很方便的工具,而最近我在搜集各种数据时候,也需要进行大量的数据转移,并且数据库和所转移的数据库表都不同,这次给大家介绍个最简单的方法,就是使 ...
- Python内存管理机制-《源码解析》
Python内存管理机制 Python 内存管理分层架构 /* An object allocator for Python. Here is an introduction to the layer ...
- OC语言-NSMutableArray为什么要用strong来修饰
Talk is cheap show you my code! NSMutableArray属性为什么要用strong来修饰,其实就是一个深复制和浅复制的问题. <pre name=" ...
- ZooKeeper搭建集群
ZooKeeper ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.它是一个为分布式应用提供一致性 ...
- @atcoder - AGC003F@ Fraction of Fractal
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个 H*W 黑白格图,保证黑格四连通. 定义分形如下:0 ...