Android okhttp https TrustManager简单总结
在okhttp源码解析中详细的分析了下其内部原理,现在就okhttp配置https的东东做一个简单的笔记。
网上查询的一些Okhttp中忽略HTTPS验证的代码如下所示。
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
//该方法在服务端使用,用来校验客户端的安全性
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
//该方法在客户端使用,用来校验服务端的安全性
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}};
忽略验证这种做法肯定不可取,对于客户端APP来说,在TrustManager中有一个方法需要我们关注,就是checkServerTrusted。顾名思义,就是用来验证服务器是否可靠。其中第一个参数是证书链,往往数组中第一个X509Certificate对象就是我们APP服务器的证书对象。通过该对象,我们可以获取证书的序列号,公钥等各种信息。
默认如果什么都不写的话,就是默认所有服务器都可靠。直接一路绿灯,畅通无阻。
注意该方法抛出一个异常CertificateException,如果自己实现这个方法,并且抛出这个异常的话,那么就说明服务器认证不通过,此时https请求返回的状态码会报600错误。比如X509Certificate对象的checkValidity方法就会抛出CertificateException的两个之类异常:一个是证书过期,一个是证书失效。
public abstract void checkValidity(Date date)
throws CertificateExpiredException, CertificateNotYetValidException;
所以我们如果简单的将checkServerTrusted如下写法的话,如果证书校验失败,HTTPS请求就会访问不通。比如我将手机系统时间往后设置30年,此时证书已经过期,运行后就会抛出CertificateExpiredException异常:
public void checkServerTrusted(java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
//服务器验失败会抛异常
chain[0].checkValidity();
}
如果我们证书校验失败,我们想要给用户提示的话,就可以先捕获了CertificateException异常,在catch里面处理:
public void checkServerTrusted(java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
try{
chain[0].checkValidity();
}catch(CertificateExpiredException e1){
//给用户弹出安全性提示
}catch(CertificateNotYetValidException e2){
//给用户弹出安全性提示
}
}
其实可以这么做,这部分可以参考Android App 安全的HTTPS 通信:
1、打包一份到证书到 app 内部,通过CertificateFactory 加载证书输入流,获取Certificate对象
2、自定义一个TrustManager,根据服务端传过来的证书链如步骤1生成的Certificate做对比,自己实现校验逻辑,代码如下:
try {
//获取本地证书
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = new BufferedInputStream(getAssets().open("certName.crt"));
final Certificate ca;
try {
ca = cf.generateCertificate(caInput);
} finally {
caInput.close();
}
SSLContext context = SSLContext.getInstance("TLSv1","AndroidOpenSSL");
context.init(null, new TrustManager[]{
new X509TrustManager() {
@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType)
throws CertificateException {
for (X509Certificate cert : chain) {
cert.checkValidity();
//省略try catch
cert.verify(((X509Certificate) ca).getPublicKey());
}
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
}, null);
关于TrustManager暂且写这么多。其具体的实现逻辑可以移步博主的Android RootTrustManager 证书校验简单分析了解更多。
相关文章
- Android面试题(四大组件篇)[通俗易懂]
- Android实现点击两次返回退出APP
- android 安装p12证书,如何在Android中使用p12证书(客户端证书)
- android sdk根目录,Android SDK位置
- robotium android,Robotium 测试Android apk安装包
- android telephony 原理解析与开发指南_Android逆向pdf
- Android preference_android studio preview
- android线程间通信的几种方法_Android进程间和线程间通信方式
- Android Services Library_android freeware
- 一种基于Android、iOS系统的移动端身份证识别技术,手机拍照识别提取身份证信息
- 【Android应用开发】Android 蓝牙低功耗 (BLE) ( 第一篇 . 概述 . 蓝牙低功耗文档 翻译)
- 【Android NDK 开发】JNI 方法解析 ( JNIEXPORT 与 JNICALL 宏定义作用 )
- 【Android UI】贝塞尔曲线 ④ ( 使用 android.graphics.Path 提供的 cubicTo 方法绘制三阶贝塞尔曲线示例 )
- 【Android Gradle 插件】自定义 Gradle 任务 ⑤ ( 为自定义 Gradle 任务添加依赖任务 | Gradle 任务依赖执行顺序控制 )
- Android控制文字水平间距android:letterSpacing详解手机开发
- 窃听风暴: Android平台https嗅探劫持漏洞
- 你的Android不好用,都是因为这几点原因
- Android实现PHP连接MySQL进行数据交互(android通过php连接mysql)
- Redis安全之旅HTTPS进行跳转(redis跳转https)
- android控件封装自己封装的dialog控件
- android分辨率适配的方法
- android自定义Android菜单背景的代码
- Android工程:引用另一个Android工程的方法详解
- Android静态变量的生命周期简单介绍