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. vc程序设计--图形绘制2

    // 实验2.cpp : 定义应用程序的入口点. // #include "framework.h" #include "实验2.h" #define MAX_ ...

  2. 【MetaPruning】2019-ICCV-MetaPruning Meta Learning for Automatic Neural Network Channel Pruning-论文阅读

    MetaPruning 2019-ICCV-MetaPruning Meta Learning for Automatic Neural Network Channel Pruning Zechun ...

  3. Rocket - interrupts - NullIntSource

    https://mp.weixin.qq.com/s/Fn3u2OSLAzPDrlZTiLfikg 简单介绍NullIntSource的实现. 1. 简单介绍 NullIntSource实现一个不会发 ...

  4. Maven_setting文件/解释

    setting文件解释: setting.xml配置文件 maven的配置文件settings.xml存在于两个地方: 1.安装的地方:${M2_HOME}/conf/settings.xml 2.用 ...

  5. Java实现 蓝桥杯VIP 算法提高 密码锁

    算法提高 题目 2 密码锁 时间限制:1.0s 内存限制:1.0GB 问题描述 你获得了一个据说是古代玛雅人制作的箱子.你非常想打开箱子看看里面有什么东西,但是不幸的是,正如所有故事里一样,神秘的箱子 ...

  6. 第五届蓝桥杯JavaA组国(决)赛真题

    解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.海盗分金币 有5个海盗,相约进行一次帆船比赛. 比赛中天气发生突变,他们被冲散了. 恰巧,他们都先后经过途中的一个无名的荒岛,并且每个 ...

  7. java实现第六届蓝桥杯立方体自身

    立方变自身 题目描述 观察下面的现象,某个数字的立方,按位累加仍然等于自身. 1^3 = 1 8^3 = 512 5+1+2=8 17^3 = 4913 4+9+1+3=17 - 请你计算包括1,8, ...

  8. CentOS8.1中搭建Gitlab服务器

    依旧是写在前面的话♠:很多IT人从业N年也许都还没有亲自搭过一次Gitlab服务器,是不是?有木有?!通常都是背着自己的笔记电脑到一家公司入职,或入职后领到公司分配的电脑,然后分配了Git账号,拿了将 ...

  9. [寒假学习]ps知识

    小学就开始学了,还是要感谢当时年轻不懂事到处研究怎么画画哈哈哈哈,不过到现在有点忘,寒假在家禁足也无聊,寻思着重拾画笔来着,复习一下,冲! 为了防止看完就忘用博客记录一下小笔记   1. 一些快捷键的 ...

  10. HTML 5的革新——语义化标签section和article的区别

    原文地址:https://stackoverflow.com/questions/33910294/what-is-the-difference-between-article-and-section ...