前言

很多公司考虑到安全问题,项目中都采用https加密协议进行数据传输。但是一些公司又不想花一笔钱去CA申请证书,所以就采用自签名的证书。
OkHttp默认是可以访问通过CA认证的HTTPS链接,例如百度首页也是https链接(https://www.baidu.com/)。但是如果是你们公司自签名(即自己用keytool生成的证书,而不是采用通过CA认证的证书)的服务器,OkHttp是无法访问的,例如访问12306网站(https://kyfw.12306.cn/otn/),会报如下错误:
HTTPS的工作原理
HTTPS在传输数据之前需要客户端(浏览器)与服务端(网站)之间进行一次握手,在握手过程中将确立双方加密传输数据的密码信息。握手过程的简单描述如下:
握手过程中如果有任何错误,都会使加密连接断开,从而阻止了隐私信息的传输。
使用OKHTTP请求自签名的https服务器数据
以下我们使用12306网站为例
1. 首先去12306网站首页下载证书 http://www.12306.cn/
2. 将下载的证书srca.cer放到工程的assets文件夹下。
3. 添加HTTPS工具类
package com.alpha58.okhttp;
import android.content.Context;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.Arrays;
import java.util.Collection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import okhttp3.OkHttpClient;
/**
* Created by admin on 2017/03/12.
*/
public final class HTTPSUtils {
private OkHttpClient client;
public Context mContext;
/**
* 获取OkHttpClient实例
* @return
*/
public OkHttpClient getInstance()
{
return client;
}
/**
* 初始化HTTPS,添加信任证书
* @param context
*/
public HTTPSUtils(Context context) {
mContext = context;
X509TrustManager trustManager;
SSLSocketFactory sslSocketFactory;
final InputStream inputStream;
try {
inputStream = mContext.getAssets().open("srca.cer"); // 得到证书的输入流
try {
trustManager = trustManagerForCertificates(inputStream);//以流的方式读入证书
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{trustManager}, null);
sslSocketFactory = sslContext.getSocketFactory();
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
}
client = new OkHttpClient.Builder()
.sslSocketFactory(sslSocketFactory, trustManager)
.build();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 以流的方式添加信任证书
*/
/**
* Returns a trust manager that trusts {@code certificates} and none other. HTTPS services whose
* certificates have not been signed by these certificates will fail with a {@code
* SSLHandshakeException}.
* <p>
* <p>This can be used to replace the host platform's built-in trusted certificates with a custom
* set. This is useful in development where certificate authority-trusted certificates aren't
* available. Or in production, to avoid reliance on third-party certificate authorities.
* <p>
* <p>
* <h3>Warning: Customizing Trusted Certificates is Dangerous!</h3>
* <p>
* <p>Relying on your own trusted certificates limits your server team's ability to update their
* TLS certificates. By installing a specific set of trusted certificates, you take on additional
* operational complexity and limit your ability to migrate between certificate authorities. Do
* not use custom trusted certificates in production without the blessing of your server's TLS
* administrator.
*/
private X509TrustManager trustManagerForCertificates(InputStream in)
throws GeneralSecurityException {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(in);
if (certificates.isEmpty()) {
throw new IllegalArgumentException("expected non-empty set of trusted certificates");
}
// Put the certificates a key store.
char[] password = "password".toCharArray(); // Any password will work.
KeyStore keyStore = newEmptyKeyStore(password);
int index = 0;
for (Certificate certificate : certificates) {
String certificateAlias = Integer.toString(index++);
keyStore.setCertificateEntry(certificateAlias, certificate);
}
// Use it to build an X509 trust manager.
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, password);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:"
+ Arrays.toString(trustManagers));
}
return (X509TrustManager) trustManagers[0];
}
/**
* 添加password
* @param password
* @return
* @throws GeneralSecurityException
*/
private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {
try {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); // 这里添加自定义的密码,默认
InputStream in = null; // By convention, 'null' creates an empty key store.
keyStore.load(in, password);
return keyStore;
} catch (IOException e) {
throw new AssertionError(e);
}
}
}
4.代码中请求
public void getHttpsHtml(View view) {
Request request = new Request.Builder()
.url("https://kyfw.12306.cn/otn/")
.build();
HTTPSUtils httpsUtils = new HTTPSUtils(this);
httpsUtils.getInstance().newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
System.out.println("--------------onFailure--------------" + e.toString());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
System.out.println("--------------onResponse--------------" + response.body().string());
}
});
}
5. 最后能打印出这些信息就说明请求成功啦!
注意:别忘了加权限和依赖okhttp库
Demo地址:https://github.com/Alpha58/okhttps
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# android
# https自签名请求
# https请求
# android使用https请求
# Android中使用OkHttp包处理HTTP的get和post请求的方法
# Android使用OkHttp发送post请求
# Android小知识之OkHttp的2种请求方式详解
# Android Okhttp请求查询购物车的实例代码
# Android基于OkHttpUtils网络请求的二次封装
# 详解Android中使用OkHttp发送HTTP的post请求的方法
# Android M(6.x)使用OkHttp包解析和发送JSON请求的教程
# 详解Android的OkHttp包编写异步HTTP请求调用的方法
# android实现okHttp的get和post请求的简单封装与使用
# 会报
# 首页
# 过程中
# 自己的
# 公钥
# 并将
# 考虑到
# 自定义
# 为例
# 又不
# 会使
# 别忘了
# 将由
# 中都
# 工作原理
# 服务端
# 大家多多
# 一笔钱
# 字串
# 客户端
相关文章:
建站主机默认首页配置指南:核心功能与访问路径优化
专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?
javascript中的try catch异常捕获机制用法分析
浅谈Javascript中的Label语句
网页设计与网站制作内容,怎样注册网站?
Thinkphp 中 distinct 的用法解析
网页设计网站制作软件,microsoft office哪个可以创建网页?
建站上传速度慢?如何优化加速网站加载效率?
在线制作视频网站免费,都有哪些好的动漫网站?
建站主机核心功能解析:服务器选择与网站搭建流程指南
武汉网站如何制作,黄黄高铁武穴北站途经哪些村庄?
股票网站制作软件,网上股票怎么开户?
网站专业制作公司,网站编辑是做什么的?好做吗?工作前景如何?
建站10G流量真的够用吗?如何应对访问高峰?
开心动漫网站制作软件下载,十分开心动画为何停播?
如何获取上海专业网站定制建站电话?
如何选择高效便捷的WAP商城建站系统?
如何批量查询域名的建站时间记录?
网站制作费用多少钱,一个网站的运营,需要哪些费用?
如何选择长沙网站建站模板?H5响应式与品牌定制哪个更优?
建站主机CVM配置优化、SEO策略与性能提升指南
上海制作企业网站有哪些,上海有哪些网站可以让企业免费发布招聘信息?
如何快速上传自定义模板至建站之星?
山东云建站价格为何差异显著?
建站之星CMS五站合一模板配置与SEO优化指南
如何高效利用亚马逊云主机搭建企业网站?
贸易公司网站制作流程,出口贸易网站设计怎么做?
东莞市网站制作公司有哪些,东莞找工作用什么网站好?
攀枝花网站建设,攀枝花营业执照网上怎么年审?
建站主机选购指南:核心配置优化与品牌推荐方案
如何高效生成建站之星成品网站源码?
如何配置FTP站点权限与安全设置?
nginx修改上传文件大小限制的方法
建站之星2.7模板:企业网站建设与h5定制设计专题
表情包在线制作网站免费,表情包怎么弄?
建站主机解析:虚拟主机配置与服务器选择指南
,交易猫的商品怎么发布到网站上去?
建站为何优先选择香港服务器?
专业网站设计制作公司,如何制作一个企业网站,建设网站的基本步骤有哪些?
制作网站哪家好,cc、.co、.cm哪个域名更适合做网站?
网站制作中优化长尾关键字挖掘的技巧,建一个视频网站需要多少钱?
音响网站制作视频教程,隆霸音响官方网站?
建站之星如何快速更换网站模板?
如何用景安虚拟主机手机版绑定域名建站?
黑客如何通过漏洞一步步攻陷网站服务器?
高防服务器:AI智能防御DDoS攻击与数据安全保障
建站之星备案是否影响网站上线时间?
广平建站公司哪家专业可靠?如何选择?
如何自定义建站之星网站的导航菜单样式?
如何构建满足综合性能需求的优质建站方案?
*请认真填写需求信息,我们会在24小时内与您取得联系。