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是否对服务证书合法性校验的新的体会的更多相关文章

  1. Android中使用GoogleMap的地理位置服务

    写在前面:android中使用地理位置功能,可以借助Google给我们提供的框架,要是有地理位置功能,你需要引用Google Play Services,请在sdk manager中下载.如果你还要使 ...

  2. Android中获取正在运行的服务-------ActivityManager.RunningServiceInfo的使用

    关于PackageManager和ActivityManager的使用 ,自己也写了一些DEMO 了,基本上写的线路参考了Settings模块下的 应用程序,大家如果真正的有所兴趣,建议大家看看源码, ...

  3. Android中Chronometer 计时器和震动服务控件

    Chronometer 计时器控件 首先在布局文件中添加chronometer控件:然后在mainActivity中获取到该控件 4 然后通过Button时间监听器中开启计时操作 5 chronome ...

  4. https请求之绕过证书安全校验工具类(原)

    package com.isoftstone.core.util; import java.io.BufferedReader; import java.io.ByteArrayOutputStrea ...

  5. https请求之绕过证书安全校验相关配置

    需在weblogic服务器上配置内存溢出的地方加入一行配置: -DUseSunHttpHandler=true      注:空格隔开 然后调用工具类:https://www.cnblogs.com/ ...

  6. HTTPS 原理浅析及其在 Android 中的使用

    作者:曹丰斌   本文首先分析HTTP协议在安全性上的不足,进而阐述HTTPS实现安全通信的关键技术点和原理.然后通过抓包分析HTTPS协议的握手以及通信过程.最后总结一下自己在开发过程中遇到的HTT ...

  7. Android中Service和Activity之间的通信

    启动Service并传递数据进去: Android中通过Intent来启动服务会传递一个Intent过去. 可以在Intent中通过putExtra()携带数据 Intent startIntent ...

  8. android中开启线程

    其实Android启动线程和JAVA一样有两种方式,一种是直接Thread类的start方法,也就是一般写一个自己的类来继承Thread类.另外一种方式其实和这个差不多啊! 那就是Runnable接口 ...

  9. Https通信原理及Android中实用总结

    一.背景 Http俨然已经成为互联网上最广泛使用的应用层协议,随着应用形态的不断演进,传统的Http在安全性上开始面临挑战,Http主要安全问题体现在: 1,信息内容透明传输. 2,通信对方的身份不可 ...

随机推荐

  1. 小谢第10问:前端JS下载文件、表格

    对于小型文件及表格下载,一般采用a标签形式 <buttonb @click="downloadTemplate()">模板下载</button> downl ...

  2. Rocket - util - HeterogeneousBag

    https://mp.weixin.qq.com/s/5hNM4yeQjaLvAJzgMG9PGQ   介绍HeterogeneousBag的实现.   ​​   1. 基本介绍   一个口袋(bag ...

  3. Java实现 蓝桥杯VIP 算法训练 猴子分苹果

    问题描述 秋天到了,n只猴子采摘了一大堆苹果放到山洞里,约定第二天平分.这些猴子很崇拜猴王孙悟空,所以都想给他留一些苹果.第一只猴子悄悄来到山洞,把苹果平均分成n份,把剩下的m个苹果吃了,然后藏起来一 ...

  4. Java实现 蓝桥杯VIP 算法提高 交换Easy

    算法提高 交换Easy 时间限制:1.0s 内存限制:512.0MB 问题描述 给定N个整数组成的序列,每次交换当前第x个与第y个整数,要求输出最终的序列. 输入格式 第一行为序列的大小N(1< ...

  5. java实现数字的值返回

    以下的静态方法实现了:把串 s 中第一个出现的数字的值返回. 如果找不到数字,返回-1 例如: s = "abc24us43" 则返回 2 s = "82445adb5& ...

  6. Linux 源码包服务的管理

    源码包安装服务的启动 使用绝对路径,调用启动脚本来启动.不同源码包的启动脚本不同,可以查看源码包的安装说明,查看启动脚本的方法 /usr/local/apache2/bin/apachectl sta ...

  7. 哪些年,我们玩过的Git

    作者:玩世不恭的Coder公众号:玩世不恭的Coder时间:2020-06-05说明:本文为原创文章,未经允许不可转载,转载前请联系作者 哪些年,我们玩过的Git 前言一.前期工作常用基本概念的理解G ...

  8. ClickHouse基本操作(一)

    常用SQL 创建表 1 2 3 4 5 6 7 CREATE TABLE b6logs( eventDate Date, impid UInt64, uid String, idfa String, ...

  9. 【JVM故事】了解JVM的结构,好在面试时吹牛

    class文件格式 参考上一篇文章<[JVM故事]一个Java字节码文件的诞生记>,后续还会专门讲解class文件的内部结构. 数据类型 jvm包括两种数据类型,基本类型和引用类型. 基本 ...

  10. CSAPP 5 - 优化程序性能

    CSAPP 5 - 优化程序性能 1. 概述 首当其冲的,还是要编写出好的算法和数据结构,优化内部结构 其次才是编写出能让编译器 易优化的,高效的可执行代码.这点在特定的机器上可能有着特定的不同的优化 ...