赞
踩
最近使用 OkHttp 访问 https 请求时,在个别 Android 设备上遇到了几个问题,搜罗网上资料,经过一番实践后,问题得到了解决,同时,我也同步升级了我的 https 证书忽略库 ANoSSL ,在此,对搜集到的资料和问题解决方案做个记录。
文章中的代码实现可到 GitHub 仓库中自行获取:
要想让 OkHttp 支持 https 请求,需要先对 https 证书协议以及 OkHttp 的支持情况有个大概了解:
SSL
和 TLS
两种协议,TLS (Transport Layer Security) 是 SSL 的升级版本,可以修复现有的 SSL 漏洞。SSLv3
支持,2019 年(3.13.x)开始放弃对 TLSv1
和 TLSv1.1
的支持,以 TLSv1.2
为最低支持标准。资料来源:
我找了几个网站,它们支持的 https 证书协议支持情况如下:
支持协议 | www.baidu.com | www.fresco-cn.org | api.github.com |
---|---|---|---|
TLS1.3 | No | No | Yes |
TLS1.2 | Yes | Yes | Yes |
TLS1.1 | Yes | Yes | No |
TLS1.0 | Yes | Yes | No |
SSL3.0 | Yes | No | No |
SSL2.0 | No | No | No |
数据来源:
可以看到,这几个网站都支持 TLS1.2
,而对于其他的 ssl 协议的支持力度各不相同,目前来说,TLS1.2
才是主流,但有可能存在个别网站不支持,所以,我们在使用 OkHttp 发起 https 请求之前,首先要搞清楚,就是服务端(接口)支持的 ssl 协议有哪些。确认好服务端的 ssl 协议支持情况后,就可以开始配置客户端的 OkHttp 了。
这里有个问题,是否只要发送 https 请求,就一定需要给 OkHttp 配置 https 校验呢?答案是非必须的,正常情况下 OkHttp 会使用默认的系统配置,用于访问一般的 https 请求足以,但往往有一些特殊情况,就需要我们在工程中进行单独配置并实现校验规则,例如以下几种情况:
好了,下面开始对 OkHttp 进行配置,大体分两步:
SSLSocketFactory
:用于指定支持某种 ssl 协议的 SocketFactoryHostnameVerifier
:用于检查证书中的主机名与使用该证书的服务器的主机名是否一致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 证书大体分为 SSL
和 TLS
两种协议,这里的 SSLSocketFactory
也一样,以下是两种协议对应的创建方式,它们仅仅只是在获取 SSLContext
实例时传的参数不同而已:
// SSL(不推荐)
public static SSLSocketFactory getSSLSocketFactory() {
try {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。