Https系列之四:https的SSL证书在Android端基于okhttp,Retrofit的使用
Https系列会在下面几篇文章中分别作介绍:
一:https的简单介绍及SSL证书的生成
二:https的SSL证书在服务器端的部署,基于tomcat,spring boot
三:让服务器同时支持http、https,基于spring boot
四:https的SSL证书在Android端基于okhttp,Retrofit的使用
所有文章会优先在:
微信公众号“颜家大少”中发布
转载请标明出处
先来回顾一下
前面已分别介绍了https,SSL证书的生成,并完成了服务器端的https的部署
并提到一个重要的用于客户端的证书:公钥证书
在前面文章中,自签名SSL证书对应的公钥证书为:mycer.cer(当然这名字是自己随便定的);在阿里云申请的CA证书中对应的公钥证书为:*.pem
如果有不清楚的,请看我之前介绍过的文章
Android自带的可信任的CA公钥证书
还要说明一下,Android系统有自带的安卓认可的证书颁发机构(如:Wosign)颁发的可信任的CA公钥证书,大概有100多个,
可自己查看,各个手机的查看方法可能不一样,在我的手机中,能在下面的位置中找到:
“设置”->”更多设置“->”系统安全“->”信任的凭据”
也就是说,如果你服务器的证书是安卓认可的证书颁发机构颁发的,那么你并不需要在Android端额外安装公钥证书,否则,你就需要安装。
注:在不同版本的Android系统上,可信任的CA证书可能是不一样的,如果你担心在别人的Android系统上可能此CA证书不被信任,那你统一都安装也是没问题的
我在阿里云上申请的免费型DV SSL证书,是属于安卓认可的证书颁发机构颁发的,不需要额外安装,当然我们的自签名证书,是必需要安装的
其实我在测试的过程中,把自签名证书和阿里云上申请的免费型DV SSL证书都用同样的方法安装了,都是OK的
我们下面就开始基于okhttp来安装公钥证书了
先看看我的okhttp和retrofit的gradle版本
compile 'com.squareup.okhttp3:okhttp:3.8.1'
compile 'com.squareup.retrofit2:retrofit:2.3.0'
增加一个OkhttpManager类
统一处理OkHttpClient的证书,完整的代码如下:
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;
public class OkhttpManager {
static private OkhttpManager mOkhttpManager=null;
private InputStream mTrustrCertificate;
static public OkhttpManager getInstance()
{
if(mOkhttpManager==null)
{
mOkhttpManager=new OkhttpManager();
}
return mOkhttpManager;
}
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);
}
}
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];
}
public void setTrustrCertificates(InputStream in)
{
mTrustrCertificate=in;
}
public InputStream getTrustrCertificates()
{
return mTrustrCertificate;
}
public OkHttpClient build()
{
OkHttpClient okHttpClient=null;
if(getTrustrCertificates()!=null)
{
X509TrustManager trustManager;
SSLSocketFactory sslSocketFactory;
try {
trustManager = trustManagerForCertificates(getTrustrCertificates());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] { trustManager }, null);
sslSocketFactory = sslContext.getSocketFactory();
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
}
okHttpClient=new OkHttpClient.Builder()
.sslSocketFactory(sslSocketFactory, trustManager)
.build();
}
else
{
okHttpClient=new OkHttpClient.Builder()
.build();
}
return okHttpClient;
}
}
代码解释
代码不少,其实最核心的代码为:
public OkHttpClient build()
{
.......
trustManager = trustManagerForCertificates(getTrustrCertificates());
.......
okHttpClient=new OkHttpClient.Builder()
.sslSocketFactory(sslSocketFactory, trustManager)
.build();
..........
return okHttpClient;
}
也就是通过
void setTrustrCertificates(InputStream in)
把自己的证书对应的文件set进去
然后通过
trustManager =trustManagerForCertificates(getTrustrCertificates());
再
okHttpClient=new OkHttpClient.Builder()
.sslSocketFactory(sslSocketFactory, trustManager)
.build();
就能生成安装好了可信任证书的okHttpClient
OkhttpManager说完了,接下来,就是:
Activity中使用OkhttpManager
1:先把公钥证书文件(如:自签名的mycer.cer或CA证书的:*.pem)放到assets下,
如果使用AndroidStudio的同学,可能没有assets文件夹,自己建此文件夹,如我的为:app\src\main\assets
2:直接贴Activity主要的代码:
public class MyActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
OkhttpManager.getInstance().setTrustrCertificates(getAssets().open("mycer.cer");
OkHttpClient mOkhttpClient= OkhttpManager.getInstance().build();
} catch (IOException e) {
e.printStackTrace();
}
}
简单吧,主要代码就那两句,就生成了已安装公钥证书”mycer.cer”的mOkhttpClient
接下来的mOkhttpClient怎样使用,大家都应该清楚了吧,如果不清楚只能看OkHttpClient的基础内容了
好了,OkHttpClient搞掂了
接下来就到Retrofit了
大家应该知到Retrofit默认是以OkHttpClient来作为传输的,既然OkHttpClient搞掂了,那Retrofit就简单了
还是直接贴代码:
Retrofit retrofit = new Retrofit.Builder()
.client(mOkhttpClient)
.baseUrl("your_serverl_url")
.build();
看,只需在Retrofit中多加一句
.client(mOkhttpClient)
就把已安装了证书的mOkhttpClient作为Retrofit的传输了
更多内容,请关注微信公众号:颜家大少
Https系列之四:https的SSL证书在Android端基于okhttp,Retrofit的使用的更多相关文章
- Https系列之一:https的简单介绍及SSL证书的生成
Https系列会在下面几篇文章中分别作介绍: 一:https的简单介绍及SSL证书的生成二:https的SSL证书在服务器端的部署,基于tomcat,spring boot三:让服务器同时支持http ...
- TortoiseGit 访问https远程仓库,上报SSL证书错误解决方法
报错 在使用TortoiseGit时,clone自己搭建的gitlab报如错SSL certificate problem: self signed certificate 原因:自行搭建的gitla ...
- [从零开始搭网站六]为域名申请免费SSL证书(https),并为Tomcat配置https域名所用的多SSL证书
点击下面连接查看从零开始搭网站全系列 从零开始搭网站 由于国内的网络环境比较恶劣,运营商流量劫持的情况比较严重,一般表现为别人打开你的网站的时候会弹一些莫名其妙的广告...更过分的会跳转至别的网站. ...
- postman进行https接口测试所遇到的ssl证书问题,参考别人方法
参考文档: https://learning.getpostman.com/docs/postman/sending_api_requests/certificates/ 随着 https 的推动,更 ...
- linux c++ curl https 请求并双向验证SSL证书
1.配置curl https请求需要提供 CA证书.客户端证书和客户端秘钥,这三个文件的pem格式. 分别对应 curl_easy_setopt() 函数的 下面三个参数: CURLOPT_CAINF ...
- 部署asp.net core Kestrel 支持https 使用openssl自签ssl证书
通过openssl生成证书 openssl req -newkey rsa:2048 -nodes -keyout my.key -x509 -days 365 -out my.cer openssl ...
- 微信小程序HTTPS - cenos apache 下安装SSL证书
1.yum install mod_ssl 2.接下来,我们需要创建一个新目录,我们将存储服务器密钥和证书 mkdir /root/ssl 3.vi /etc/httpd/conf.d/ssl.con ...
- 请求https前缀的网站验证SSL证书的解决方案之一
from requests.packages.urllib3.exceptions import InsecureRequestWarning # 禁用安全请求警告requests.packages. ...
- Loadrunner对https协议(单双向SSL)的web端性能测试
1.项目背景 1.1 单双向SSL的含义及部署 单向SSL即我们说到的https协议. 特点是,浏览器需要请求验证服务器证书: 基本含义是:一个安全通信通道,它基于HTTP开发,用于在客户计算机和服务 ...
随机推荐
- python+selenium自动化软件测试(第9章) :Logging模块
9.1 Logging模块 什么是日志记录?记录是跟踪运行时发生的事件的一种手段.该软件的开发人员将记录调用添加到其代码中,以指示某些事件已发生.事件由描述性消息描述,该消息可以可选地包含可变数据(即 ...
- JAVA奇技淫巧简化代码之lombok
背景 最近在做一个小功能,又不想在原有体态臃肿的项目中追加,为了调试方便并且可以快速开发就采用了springboot.由于使用了JPA,建了几个类,然后通过IDE去生成其属性的构造器.getter.s ...
- Mysql数据库索引
今天,我们来讲讲Mysql数据库的索引的一些东西,想必大家都知道索引能干吗?必然是查找数据表的时候,查找的速度快啊,尤其是那些几百万行的数据库,不建立索引,你是想考验用户的耐心吗?Mysql有多种存储 ...
- Visual Studio 2013怎么关闭智能提示?
visual studio的智能提示加快了程序员写代码的速度,但是却让程序员更加的依赖编辑器,离开了智能提示,会忘记很多代码~,甚至会问自己,我还是程序员吗? 下面给出关闭visual studio智 ...
- window 使用git 非ssh key 面密码登录
Windows下使用git bash时,总是提示输入用户名密码,严重影响了开发效率,经搜索查找找到了如下有效的解决方案,屡试不爽! 1.先创建存储用户名密码的文件 ,在home文件夹,一般是 C:\D ...
- Cython的用法以及填坑姿势
因为项目需要,需要优化已有的Python代码.目前Python代码的执行过程是将Python代码转变成一行行指令,然后解释器解释指令的执行,调用到C代码层.如果去掉指令解释这个阶段,直接进入C代码层, ...
- https加密实现
author:JevonWei 版权声明:原创作品 在httpd安装完成的基础上实现https加密 安装mod_ssl软件包 yum -y install mod_ssl http -M 显示mod_ ...
- chrome开发工具指南(二)
Application 面板 使用 App Manifest 窗格检查您的网络应用清单和触发 Add to Homescreen 事件. 使用 Service Worker 窗格执行与服务工作线程相关 ...
- Java 得到磁盘以及内存信息
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt217 1.得到磁盘信息 File[] files = File. listR ...
- IT经典书籍——Head First系列【推荐】
Head First 系列书籍是由 O'Relly 出版社发行的一系列教育书籍,中文一般翻译为"深入浅出",它强调以特殊的方式排版,由大量的图片和有趣的内容组合构成,而达到非疲劳的 ...