为了确保数据传输的安全,现在越来越多的应用使用Https的方式来进行数据传输,使用https有很多有点,比如:

  • HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性。
  • HTTPS是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。

但是即使使用HTTPS有很多有点,但是购买一个认证的HTTPS证书却价格不菲,增加了初创企业和小团队的开发成本。而且如上面所说,使用HTTPS并非绝对的安全,传输的数据并非没有办法获取到,我的之前一篇博客所使用的方法已成功截取HTTPS的数据传输。有兴趣的可以参考:使用Charles对Android App的https请求进行抓包

为了节约成本,我们可以选择使用自签名的HTTPS。

这种方式我们可以自己生成证书,不需要购买证书,但是使用这种方式的域名如果在浏览器中访问的话,会有一个不安全的标识。但是如果用在客户端上,就不会有这个问题,现在一些应用商店也要求APP上架时需要使用HTTPS的网络请求(比如AppStore),使用这种自签名的HTTPS同样也能过审。

本文我们介绍在Android上使用网络请求框架Retrofit 2来请求自签名的API,关于如何生成HTTPS证书,我们将在另一篇博客中进行说明,敬请期待。或者您可以自行查找相关资料。

配置证书

比如我们生成的SLL证书文件为"api_ssl_debug.cer",我们将其放到assets目录下。这样在配置Retrofit的时候就可以读取该证书并用于API请求中。

配置Retrofit

本节我们介绍SSL证书在Retrofit中的配置,首先我们要定义两个方法用来读取证书,然后讲该证书用于Retrofit中。

  1. 读取证书内容到KeyStore中
    private static KeyStore getKeyStore(String fileName) {
KeyStore keyStore = null;
try {
AssetManager assetManager = Utils.getApp().getAssets();
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = assetManager.open(fileName);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
Log.d("SslUtils", "ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
} String keyStoreType = KeyStore.getDefaultType();
keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
} catch (Exception e) {
Log.e("SslUtils", "Error during getting keystore", e);
}
return keyStore;
}
  1. 生成SSLContext以便用于Retrofit的配置中
    public static SSLContext getSslContextForCertificateFile(String fileName) {
try {
KeyStore keyStore = SslUtils.getKeyStore(fileName);
SSLContext sslContext = SSLContext.getInstance("SSL");
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
return sslContext;
} catch (Exception e) {
String msg = "Error during creating SslContext for certificate from assets";
Log.e("SslUtils", msg, e);
throw new RuntimeException(msg);
}
}
  1. 配置Retrofit
SSLContext sslContext = SslUtils.getSslContextForCertificateFile("api_ssl_debug.cer");

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:"
+ Arrays.toString(trustManagers));
}
X509TrustManager trustManager = (X509TrustManager) trustManagers[0]; OkHttpClient.Builder builder = new OkHttpClient.Builder()
...
.sslSocketFactory(sslContext.getSocketFactory(), trustManager)
.hostnameVerifier((hostname, session) -> true)
... mRetrofit = new Retrofit.Builder()
...
build();

以上的省略号为Retrofit的其它配置,可以根据工程需要进行配置。

总结

至此,使用Retrofit就可以进行自签名的HTTPS的网络请求了,当然,服务器端的API配置也需要进行HTTPS的配置,我将在服务端相关的博客进行介绍,还有一点,如果请求的域名指定了端口,要将端口设置为443。如果没有指定端口,请求时也会自动走443端口。

本文原始地址,如有更多疑问,请参考我的其它Android相关博客:我的博客地址

Android开发 - Retrofit 2 使用自签名的HTTPS证书进行API请求的更多相关文章

  1. Android开发时包名、签名、渠道和版本号的易坑点(转)

    本文中总结一下 Android 开发中容易被忽视的一些注意事项吧: 一.谨慎选择包名 包名 (Package Name) 就相当于一款应用在户口本上登记的名字,是系统用来区分不同应用的字段.重复的包名 ...

  2. Android开发 retrofit入门讲解

    前言 retrofit基于okhttp封装的网络请求框架,网络请求的工作本质上是 OkHttp 完成,而 retrofit 仅负责网络请求接口的封装.如果你不了解OKhttp建议你还是先了解它在来学习 ...

  3. Android开发之通过反射获取到挂断电话的API

    Android开发黑名单工具类,需要用到挂断电话的API,但是该API处于隐藏状态,需要通过反射得到该方法.. 步骤: 1.通过当前类获取到ServiceManager的字节码 Class< ? ...

  4. 《android开发进阶从小工到专家》读书笔记--HTTP网络请求

    No1: 客户端与服务器的交互流程: 1)客户端执行网络请求,从URL中解析出服务器的主机名 2)将服务器的主机名转换成服务器的IP地址 3)将端口号从URL中解析出来 4)建立一条从客户端与Web服 ...

  5. Android开发——Notification通知的使用及NotificationCopat.Builder常用设置API

    想要看全部设置的请看这一篇 [转]NotificationCopat.Builder全部设置 常用设置: 设置属性 说明 setAutoCancel(boolean autocancel) 设置点击信 ...

  6. Android开发 retrofit下载与上传

    前言 此博客只讲解retrofit下载与上传的使用,其实与其说是retrofit的下载与上传还不如说,依然是Okhttp的下载与上传.如果你需要了解retrofit入门请查看这篇博客(此博客不在详细讲 ...

  7. Android开发 retrofit入门讲解 (RxJava模式)

    前言 retrofit除了正常使用以外,还支持RxJava的模式来使用,此篇博客讲解如何使用RxJava模式下的retrofit 依赖 implementation 'com.squareup.ret ...

  8. 自签名的https证书是不安全的

    一.项目内的需求 我们做的app都是企业级的应用,而企业级的应用的下载需要遵循itms协议,itms协议下需要https链接,这就需要你的服务器支持https的协议,该协议需要申请SSL证书,我们测试 ...

  9. [置顶] Android开发笔记(成长轨迹)

    分类: 开发学习笔记2013-06-21 09:44 26043人阅读 评论(5) 收藏 Android开发笔记 1.控制台输出:called unimplemented OpenGL ES API ...

随机推荐

  1. C# 委托和泛型

    委托定义: 委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有 ...

  2. epoll的LT和ET(转)

    1 socket IO事件 1.1 读事件 读事件:句柄从不可读变成可读,或者句柄写缓冲区有新的数据进来且超过SO_RCVLOWAT. 常见的产生读事件有如下几种: socket有一个未清除的错误.如 ...

  3. ubuntu环境下,ubuntu16.04装机到nvdia显卡驱动安装、cuda8安装、cudnn安装

    首先是安装ubuntu16.04 A.制作u盘启动盘(提前准备好.ios文件): 1.安装u盘制作工具unetbootinsudo apt-get install unetbootin2.格式化u盘s ...

  4. Swagger使用

    Swagger 1.集成springboot 第一步:pom <dependency> <groupId>io.springfox</groupId> <ar ...

  5. 大数据入门到精通8-spark RDD 复合key 和复合value 的map reduce操作

    一.做基础数据准备 这次使用fights得数据. scala> val flights= sc.textFile("/user/hdfs/data/Flights/flights.cs ...

  6. Spring学习,初识Spring

    Spring概述 将Spring理解为管理对象间依赖关系的容器 “解耦” 根据功能的不同,可以将一个系统中的代码分为 主业务逻辑 与 系统级业务逻辑 两类 ```Spring 是为了解决企业级开发的复 ...

  7. java引用

    java1.2之后将引用分为强引用(Strong Reference).软引用(Soft Reference).弱引用(Weak Reference).虚引用(Phantom Reference)4种 ...

  8. hdoj4734(数位dp优化)

    题目链接:https://vjudge.net/problem/HDU-4734 题意:定义一个十进制数AnAn-1...A1的value为An*2n-1+...+A1*20,T组样例(<=1e ...

  9. Unity 2017 Game Optimization 新版

    英文原版,PDF格式带目录,非常不错的关于性能优化的书籍 扫码时备注或说明中留下邮箱 付款后如未回复请至https://shop135452397.taobao.com/ 联系店主

  10. swift 警告框 - 自定义按钮颜色,图片

    1.封装 弹框http://www.hangge.com/blog/cache/detail_651.html import UIKit extension UIAlertController { / ...