前言

很多公司考虑到安全问题,项目中都采用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请求的简单封装与使用
# 会报
# 首页
# 过程中
# 自己的
# 公钥
# 并将
# 考虑到
# 自定义
# 为例
# 又不
# 会使
# 别忘了
# 将由
# 中都
# 工作原理
# 服务端
# 大家多多
# 一笔钱
# 字串
# 客户端
相关文章:
如何快速搭建高效WAP手机网站吸引移动用户?
如何通过cPanel快速搭建网站?
如何通过山东自助建站平台快速注册域名?
建站主机数据库如何配置才能提升网站性能?
非常酷的网站设计制作软件,酷培ai教育官方网站?
Android滚轮选择时间控件使用详解
阿里云网站搭建费用解析:服务器价格与建站成本优化指南
C#如何使用XPathNavigator高效查询XML
宝塔新建站点报错如何解决?
如何选择高性价比服务器搭建个人网站?
制作网站的基本流程,设计网站的软件是什么?
专业商城网站制作公司有哪些,pi商城官网是哪个?
如何将凡科建站内容保存为本地文件?
如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?
北京制作网站的公司,北京铁路集团官方网站?
建设网站制作价格,怎样建立自己的公司网站?
C++如何将C风格字符串(char*)转换为std::string?(代码示例)
车管所网站制作流程,交警当场开简易程序处罚决定书,在交警网站查询不到怎么办?
如何在IIS中新建站点并配置端口与IP地址?
小建面朝正北,A点实际方位是否存在偏差?
详解jQuery中基本的动画方法
北京企业网站设计制作公司,北京铁路集团官方网站?
制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?
北京网页设计制作网站有哪些,继续教育自动播放怎么设置?
如何基于云服务器快速搭建网站及云盘系统?
建站之星备案是否影响网站上线时间?
如何在香港免费服务器上快速搭建网站?
如何在阿里云部署织梦网站?
宝塔建站教程:一键部署配置流程与SEO优化实战指南
如何快速搭建高效可靠的建站解决方案?
公司网站的制作公司,企业网站制作基本流程有哪些?
交易网站制作流程,我想开通一个网站,注册一个交易网址,需要那些手续?
大型企业网站制作流程,做网站需要注册公司吗?
邀请函制作网站有哪些,有没有做年会邀请函的网站啊?在线制作,模板很多的那种?
如何快速搭建二级域名独立网站?
在线流程图制作网站手机版,谁能推荐几个好的CG原画资源网站么?
深圳网站制作培训,深圳哪些招聘网站比较好?
早安海报制作网站推荐大全,企业早安海报怎么每天更换?
如何基于云服务器快速搭建个人网站?
如何使用Golang安装API文档生成工具_快速生成接口文档
建站之星代理平台如何选择最佳方案?
制作网站的公司有哪些,做一个公司网站要多少钱?
,sp开头的版面叫什么?
如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?
网站海报制作教学视频教程,有什么免费的高清可商用图片网站,用于海报设计?
如何通过老薛主机一键快速建站?
如何通过虚拟主机快速完成网站搭建?
如何选择CMS系统实现快速建站与SEO优化?
如何自定义建站之星模板颜色并下载新样式?
建站之星多图banner生成与模板自定义指南
*请认真填写需求信息,我们会在24小时内与您取得联系。