Android - OkHttp 访问 https 的怪问题

devtools/2024/9/24 17:31:16/

一、简述

最近使用 OkHttp 访问 https 请求时,在个别 Android 设备上遇到了几个问题,搜罗网上资料,经过一番实践后,问题得到了解决,同时,我也同步升级了我的 https 证书忽略库 ANoSSL ,在此,对搜集到的资料和问题解决方案做个记录。

文章中的代码实现可到 GitHub 仓库中自行获取:

  • https://github.com/GitLqr/ANoSSL

二、协议

要想让 OkHttp 支持 https 请求,需要先对 https 证书协议以及 OkHttp 的支持情况有个大概了解:

  1. 【服务端】https 证书是配置在服务端的,大体分为 SSLTLS 两种协议,TLS (Transport Layer Security) 是 SSL 的升级版本,可以修复现有的 SSL 漏洞。
  2. 【客户端】OkHttp 支持过的 https 证书协议有 SSLv3 (1996)、TLSv1 (1999)、TLSv1.1 (2006)、TLSv1.2 (2008) 和 TLSv1.3 (2018),但要注意,OkHttp 从 2014 年开始就放弃对 SSLv3 支持,2019 年(3.13.x)开始放弃对 TLSv1TLSv1.1 的支持,以 TLSv1.2 为最低支持标准。

资料来源:

  • https://aws.amazon.com/cn/compare/the-difference-between-ssl-and-tls/
  • https://medium.com/square-corner-blog/okhttp-3-13-requires-android-5-818bb78d07ce

我找了几个网站,它们支持的 https 证书协议支持情况如下:

支持协议www.baidu.comwww.fresco-cn.orgapi.github.com
TLS1.3NoNoYes
TLS1.2YesYesYes
TLS1.1YesYesNo
TLS1.0YesYesNo
SSL3.0YesNoNo
SSL2.0NoNoNo

数据来源:

  • https://www.ssleye.com/ssltool/cipher_suites.html
  • https://www.ssllabs.com/ssltest/

可以看到,这几个网站都支持 TLS1.2,而对于其他的 ssl 协议的支持力度各不相同,目前来说,TLS1.2 才是主流,但有可能存在个别网站不支持,所以,我们在使用 OkHttp 发起 https 请求之前,首先要搞清楚,就是服务端(接口)支持的 ssl 协议有哪些。确认好服务端的 ssl 协议支持情况后,就可以开始配置客户端的 OkHttp 了。

三、配置

这里有个问题,是否只要发送 https 请求,就一定需要给 OkHttp 配置 https 校验呢?答案是非必须的,正常情况下 OkHttp 会使用默认的系统配置,用于访问一般的 https 请求足以,但往往有一些特殊情况,就需要我们在工程中进行单独配置并实现校验规则,例如以下几种情况:

  1. 服务端使用了非 CA 认证的私有 https 证书
  2. 服务端使用了过期的 https 证书
  3. 客户端支持某个 ssl 协议但是默认没有启用

好了,下面开始对 OkHttp 进行配置,大体分两步:

  1. 配置 SSLSocketFactory:用于指定支持某种 ssl 协议的 SocketFactory
  2. 配置 HostnameVerifier:用于检查证书中的主机名与使用该证书的服务器的主机名是否一致
val sslSocketFactory = NoSSLSocketClient.getTLSSocketFactory()
val x509TrustManager = NoSSLSocketClient.getX509TrustManager()
val hostnameVerifier = NoSSLSocketClient.getHostnameVerifier()val okHttpClient = OkHttpClient.Builder().sslSocketFactory(sslSocketFactory,x509TrustManager // 必须指定该参数,否则 Android 10 及以上版本会闪退).hostnameVerifier(hostnameVerifier).build()

这里主要看 sslSocketFactory 是怎么创建的,前面说过,https 证书大体分为 SSLTLS 两种协议,这里的 SSLSocketFactory 也一样,以下是两种协议对应的创建方式,它们仅仅只是在获取 SSLContext 实例时传的参数不同而已:

// SSL(不推荐)
public static SSLSocketFactory getSSLSocketFactory() {try {SSLContext sslContext = SSLContext.getInstance("SSL");sslContext.init(

http://www.ppmy.cn/devtools/14824.html

相关文章

在ios设备上运行Unity Profiler

久违了朋友们。 最近基于Unity 2021.3 和AR Foundation开发了个应用,需要在ipad上实际运行时查看程序的各项指标功耗。 于是乎,我尝试跟随者官方教程来实时调试,现在附上一些心得。 按照官方的三步走,Build and Run理论上会自动…

添加修改ubuntu中环境变量(PATH)

1.打开.bashrc文件进行设置,终端执行以下命令: sudo gedit ~/.bashrc2.在末尾行添加: export PATH$PATH:/xxx/xxx 其中,$PATH代表现存的环境变量,不能省去,等号两边一定不能有空格,/xxx/xxx要…

加密安全-openssh服务

openssh服务 1、ssh配置 ssh第一次远程链接需要客户端输入yes,如下: # 109节点第一次通过ssh链接106,需要手动输入yes root109:~$ ssh 192.168.31.106 The authenticity of host 192.168.31.106 (192.168.31.106) cant be established. ED…

rocky9 yum安装 Nginx

前置条件: 把yum包更新到最新 [rootlocalhost ~]# yum update 查看系统中是否已安装 nginx 服务 rpm -qa|grep nginx 如果有安装nginx,则需要先卸载之前安装的nginx: yum -y remove nginx 然后再查看nginx是否都卸载完成,如果还有没卸载完成的&am…

NASA数据集——有源空腔辐射计辐照度监测仪(ACRIM)II 本地格式的 UARS 机载太阳总辐照度(TSI)2022年1月版本

Active Cavity Radiometer Irradiance Monitor (ACRIM) II Total Solar Irradiance (TSI) aboard UARS in Native format 简介 ACRIMII_TSI_UARS_NAT 数据是上层大气研究卫星(UARS)上的有源空腔辐射计辐照度监测仪 II(ACRIM II)…

Linux上部署Jupyter notebook

安装jupyter notebook pip install notebook #或者 conda install notebook配置 jupyter notebook --generate-config## The IP address the notebook server will listen on. # Default: localhost # 设置可以访问的ip, 默认是localhost, 将其改为 * c.NotebookApp.ip *#…

数学建模完整版

模型与适用题型 微分方程传染病预测模型 神经网络 层次分析法 粒子群算法 matlab 优劣解距离法

[前端]NVM管理器安装、nodejs、npm、yarn配置

NVM管理器安装、nodejs、npm、yarn配置 NVM管理器安装 nvm(Node.js version manager) 是一个命令行应用,可以协助您快速地 更新、安装、使用、卸载 本机的全局 node.js 版本。 nvm下载地址:https://github.com/coreybutler/nvm-windows/releases 1.全部…