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,通信对方的身份不可 ...
随机推荐
- 【Java8新特性】不了解Optional类,简历上别说你懂Java8!!
写在前面 最近,很多读者出去面试都在Java8上栽了跟头,事后自己分析,确实对Java8的新特性一知半解.然而,却在简历显眼的技能部分写着:熟练掌握Java8的各种新特性,能够迅速使用Java8开发高 ...
- HotRing: A Hotspot-Aware In-Memory Key-Value Store(FAST ’20)
本文主要解决的是基于内存的K-V存储引擎在实际应用中出现的热点问题,设计了一个热点可感知的KV存储引擎,极大的提升了KV存储引擎对于热点数据访问的承载能力. Introduction 热点问题,可 ...
- Rocket - config - implicit Parameters
https://mp.weixin.qq.com/s/OH_Z1gdSUpfgM-tjx0OlrA 追溯配置信息的源头. 0. HasRocketCoreParameters Has ...
- Java实现 LeetCode 768 最多能完成排序的块 II(左右便利)
768. 最多能完成排序的块 II 这个问题和"最多能完成排序的块"相似,但给定数组中的元素可以重复,输入数组最大长度为2000,其中的元素最大为10**8. arr是一个可能包含 ...
- Java实现 LeetCode 455 分发饼干
455. 分发饼干 假设你是一位很棒的家长,想要给你的孩子们一些小饼干.但是,每个孩子最多只能给一块饼干.对每个孩子 i ,都有一个胃口值 gi ,这是能让孩子们满足胃口的饼干的最小尺寸:并且每块饼干 ...
- Java实现 蓝桥杯VIP 算法提高 计算器
算法提高 计算器 时间限制:1.0s 内存限制:256.0MB [问题描述] 王小二的计算器上面的LED显示屏坏掉了,于是他找到了在计算器维修与应用系学习的你来为他修计算器. 屏幕上可以显示0~9的数 ...
- Java实现 LeetCode 62 不同路径
62. 不同路径 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为"Start" ). 机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角(在下图中 ...
- sqlite使用dbexpress时数据库不存在自动建立数据库
在发布使用delphi dbexpress编写的基于SQLITE的程序时,需要在运行时判断某个数据库是否存在,如果不存在,则自动建立. 方法有2,其中之一是判断数据库文件是否存在,如果不存在,则创建一 ...
- 算法讲堂二:组合数学 & 概率期望DP
组合数学 1. 排列组合 1. 加法原理 完成一列事的方法有 n 类,其中第 i 类方法包括\(a_i\)种不同的方法,且这些方法互不重合,则完成这件事共有 \(a_1 + a_2 + \cdots ...
- (一)linux三剑客之grep
给自己提出以下6个问题,看自己是否真正掌握了grep [1] grep 是什么? [2] grep 有什么作用 ? [4] grep 常用于何处 ? [5] grep 的基本用法 ? [6] grep ...