Android:Https跳过证书验证、Https使用证书、HttpClient、
来源:互联网 发布:51单片机控制步进电机 编辑:程序博客网 时间:2024/06/10 03:11
在公司用习惯了Http请求,突然要用到Https请求,因为突然换了我太不习惯,在第三方网络请求发现无用时,我开始使用原生的网络请求,突然发现完全不会Https请求。结果一段时间的总结与使用,我把这期间的使用心得发布到csdn,为了是总结知识点和广大程序猿方便。
既然叫跳过证书验证,那么我们在使用网络请求之前,就应该使用一定的手段来跳过验证。
1、首先得重写org.apache.http.conn.ssl.SSLSocketFactory这个类,从字面意思理解就是:加密套接字协议层工厂。
2、必须用到TrustManager 就是证书管理者。
3、最后就是要用到安全协议的实现类:SSLContext
接下来就一步一步完成。
1、直接继承SSLSocketFactory
public class SSLHttpsUtils extends SSLSocketFactory{/** * @param truststore * @throws NoSuchAlgorithmException * @throws KeyManagementException * @throws KeyStoreException * @throws UnrecoverableKeyException */public SSLHttpsUtils(KeyStore truststore) throws NoSuchAlgorithmException,KeyManagementException, KeyStoreException,UnrecoverableKeyException {super(truststore);}}
2、通过官方API发现原来TrustManager里面没有任何内容,只有一个间接子类X509TrustManager,通过网上查看,X509是一个通用的证书格式,只需要拿到这个一个格式就OK了。
TrustManager manager = new X509TrustManager() {@Overridepublic X509Certificate[] getAcceptedIssuers() {// TODO Auto-generated method stubreturn null;}@Overridepublic void checkServerTrusted(X509Certificate[] arg0, String arg1)throws CertificateException {// TODO Auto-generated method stub}@Overridepublic void checkClientTrusted(X509Certificate[] arg0, String arg1)throws CertificateException {// TODO Auto-generated method stub}};
3、最后把这些东西融合到一起就要用到SSLContext,通过API发现通过SSLContext.getInstance,这里我们就取最简单的,里面传参发现一个不认识的参数通过查找是一个指定的安全协议:TLS三次握手协议,最后通过init初始化这个安全协议,再把这个方法放在SSLSocketFactory的构造函数中。
<pre name="code" class="java">private SSLContext context = SSLContext.getInstance("TLS");private void initSSLContext() {try {// 既然是跳过认证,我们把没有的都填null,此时发现第二个参数是一个数组,那么意思就是我们可以放多个证书认证;context.init(null, new TrustManager[] { manager }, null);} catch (KeyManagementException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
4、以上工作做完我们就开始使用这些东西,并得到我们想要的。
public static DefaultHttpClient getNewHttpClient() {try {// 查看API这里可以得到一个默认的Type.KeyStore truststore = KeyStore.getInstance(KeyStore.getDefaultType());// 这里发现需要一个KeyStore,那么我们就在上面New一个KeyStore,这是一个密钥库,查看API发现能直接getInstance得到对象;SSLSocketFactory factory = new SSLHttpsUtils(truststore);// 这里就是我们最需要的也是最关键的一步,设置主机认证,通过API发现有一个常量就是允许所有认证通过。factory.setHostnameVerifier(ALLOW_ALL_HOSTNAME_VERIFIER);// 实现Httpprams的子类HttpParams params = new BasicHttpParams();//通过Http适配器设置必要参数,现在通用HTTP1.1协议,和UTF-8字符。HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);//通过适配器设置连接参数,等待时间和,连接时间HttpConnectionParams.setSoTimeout(params, 10000);HttpConnectionParams.setConnectionTimeout(params, 5000);// 同样New出来,查看API,需要我们注册一个计划,来封装协议细节SchemeRegistry schreg = new SchemeRegistry();// 最后一个参数是端口设置,Https常用的端口就是443。schreg.register(new Scheme("https", factory, 443));// 既然是工具类,这里也把http协议加上,中间的协议工厂我们就用简单的PlainSocketFactory,这里可以通过API查看到,端口就用常用的80端口(默认)schreg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));// ClientConnectionManager是一个借口,就实现他的子类,同样需要2个参数,第一个我们熟悉,第二个就是让我们自定义自己的一套方案协议,继续在上面一步一步完成;ClientConnectionManager conman = new SingleClientConnManager(params, schreg);// 返回我们需要的一个默认Httpclient,为了把之前做的关联起来,就new最多参数的构造函数,需要2个参数,Httpparams是我们熟悉的,// 发现ClientConnectionManager不太熟悉,通过API发现这是客服端连接管理者,既然这样,就在上面一步一步完成。return new DefaultHttpClient(conman, params);} catch (Exception e) {// TODO: handle exception}return new DefaultHttpClient();}
很多东西我是通过倒推查看API来完成的,如果没看懂,可以先通看一次,然后再倒推回去看。
最后附上完整代码:
/** * @author 李飞翔 * @ SSLHttpsUtils.java * 时间:2016-1-11 下午8:03:05 * */package com.example.boketestapplication;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;import org.apache.http.HttpVersion;import org.apache.http.conn.ClientConnectionManager;import org.apache.http.conn.scheme.PlainSocketFactory;import org.apache.http.conn.scheme.Scheme;import org.apache.http.conn.scheme.SchemeRegistry;import org.apache.http.conn.ssl.SSLSocketFactory;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.impl.conn.SingleClientConnManager;import org.apache.http.params.BasicHttpParams;import org.apache.http.params.HttpConnectionParams;import org.apache.http.params.HttpParams;import org.apache.http.params.HttpProtocolParams;import org.apache.http.protocol.HTTP;/** * @author 李飞翔 * @name SSLHttpsUtils.java * @data 2016-1-11 下午8:03:05 * @TODO */public class SSLHttpsUtils extends SSLSocketFactory {/** * @param truststore * @throws NoSuchAlgorithmException * @throws KeyManagementException * @throws KeyStoreException * @throws UnrecoverableKeyException */public SSLHttpsUtils(KeyStore truststore) throws NoSuchAlgorithmException,KeyManagementException, KeyStoreException,UnrecoverableKeyException {super(truststore);initSSLContext();}TrustManager manager = new X509TrustManager() {@Overridepublic X509Certificate[] getAcceptedIssuers() {// TODO Auto-generated method stubreturn null;}@Overridepublic void checkServerTrusted(X509Certificate[] arg0, String arg1)throws CertificateException {// TODO Auto-generated method stub}@Overridepublic void checkClientTrusted(X509Certificate[] arg0, String arg1)throws CertificateException {// TODO Auto-generated method stub}};private SSLContext context = SSLContext.getInstance("TLS");private void initSSLContext() {try {// 既然是跳过认证,我们把没有的都填null,此时发现第二个参数是一个数组,那么意思就是我们可以放多个证书认证;context.init(null, new TrustManager[] { manager }, null);} catch (KeyManagementException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static DefaultHttpClient getNewHttpClient() {try {// 查看API这里可以得到一个默认的Type.KeyStore truststore = KeyStore.getInstance(KeyStore.getDefaultType());// 这里发现需要一个KeyStore,那么我们就在上面New一个KeyStore,这是一个密钥库,查看API发现能直接getInstance得到对象;SSLSocketFactory factory = new SSLHttpsUtils(truststore);// 这里就是我们最需要的也是最关键的一步,设置主机认证,通过API发现有一个常量就是允许所有认证通过。factory.setHostnameVerifier(ALLOW_ALL_HOSTNAME_VERIFIER);// 实现Httpprams的子类HttpParams params = new BasicHttpParams();//通过Http适配器设置必要参数,现在通用HTTP1.1协议,和UTF-8字符。HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);//通过适配器设置连接参数,等待时间和,连接时间HttpConnectionParams.setSoTimeout(params, 10000);HttpConnectionParams.setConnectionTimeout(params, 5000);// 同样New出来,查看API,需要我们注册一个计划,来封装协议细节SchemeRegistry schreg = new SchemeRegistry();// 最后一个参数是端口设置,Https常用的端口就是443。schreg.register(new Scheme("https", factory, 443));// 既然是工具类,这里也把http协议加上,中间的协议工厂我们就用简单的PlainSocketFactory,这里可以通过API查看到,端口就用常用的80端口(默认)schreg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));// ClientConnectionManager是一个借口,就实现他的子类,同样需要2个参数,第一个我们熟悉,第二个就是让我们自定义自己的一套方案协议,继续在上面一步一步完成;ClientConnectionManager conman = new SingleClientConnManager(params, schreg);// 返回我们需要的一个默认Httpclient,为了把之前做的关联起来,就new最多参数的构造函数,需要2个参数,Httpparams是我们熟悉的,// 发现ClientConnectionManager不太熟悉,通过API发现这是客服端连接管理者,既然这样,就在上面一步一步完成。return new DefaultHttpClient(conman, params);} catch (Exception e) {// TODO: handle exception}return new DefaultHttpClient();}}
1 0
- Android:Https跳过证书验证、Https使用证书、HttpClient、
- 解决httpclient 4.5 https请求跳过证书验证
- okhttp和webview跳过https证书验证
- Android HTTPS 使用证书
- httpclient忽略证书验证允许https请求
- httpclient https忽略证书
- httpclient 无信任证书使用https
- httpclient 无信任证书使用https
- httpclient 无信任证书使用https
- httpclient 无信任证书使用https
- httpclient 无信任证书使用https
- httpclient 无信任证书使用https
- httpclient 无信任证书使用https
- httpclient https请求跳过验证
- Https验证证书
- Https 证书验证问题
- https之证书验证
- httpClient 连接 https + 证书连接
- C++ ATL 中list中删除操作
- 即使被拖库,也可以保证密码不泄露(一种安全的加密方案)
- github连接报"ssh: connect to host github.com port 22: Connection timed out"错误
- 消息传递机制
- 重拾编程之路--数据结构--中缀表示法转换成前缀表示法
- Android:Https跳过证书验证、Https使用证书、HttpClient、
- 归并排序
- Android系统编译APP make: ***/src/R.stamp] Segmentation fault (core dumped)出错的解决方案
- hdoj--1018--Big Number(简单数学)
- 重拾编程之路--数据结构--后缀表示序列求值
- BroadcastReceiver实现闹钟简单小例
- 《算法导论》读书笔记--计数排序&基数排序
- 联接
- 【看书】二维字符数组