一、简述
最近使用 OkHttp 访问 https 请求时,在个别 Android 设备上遇到了几个问题,搜罗网上资料,经过一番实践后,问题得到了解决,同时,我也同步升级了我的 https 证书忽略库 ANoSSL ,在此,对搜集到的资料和问题解决方案做个记录。
文章中的代码实现可到 GitHub 仓库中自行获取:
- https://github.com/GitLqr/ANoSSL
二、协议
要想让 OkHttp 支持 https 请求,需要先对 https 证书协议以及 OkHttp 的支持情况有个大概了解:
- 【服务端】https 证书是配置在服务端的,大体分为
SSL
和TLS
两种协议,TLS (Transport Layer Security) 是 SSL 的升级版本,可以修复现有的 SSL 漏洞。 - 【客户端】OkHttp 支持过的 https 证书协议有 SSLv3 (1996)、TLSv1 (1999)、TLSv1.1 (2006)、TLSv1.2 (2008) 和 TLSv1.3 (2018),但要注意,OkHttp 从 2014 年开始就放弃对
SSLv3
支持,2019 年(3.13.x)开始放弃对TLSv1
和TLSv1.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.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 |
数据来源:
- 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 请求足以,但往往有一些特殊情况,就需要我们在工程中进行单独配置并实现校验规则,例如以下几种情况:
- 服务端使用了非 CA 认证的私有 https 证书
- 服务端使用了过期的 https 证书
- 客户端支持某个 ssl 协议但是默认没有启用
好了,下面开始对 OkHttp 进行配置,大体分两步:文章来源:https://www.toymoban.com/news/detail-861801.html
- 配置
SSLSocketFactory
:用于指定支持某种 ssl 协议的 SocketFactory - 配置
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 证书大体分为 SSL
和 TLS
两种协议,这里的 SSLSocketFactory
也一样,以下是两种协议对应的创建方式,它们仅仅只是在获取 SSLContext
实例时传的参数不同而已:文章来源地址https://www.toymoban.com/news/detail-861801.html
// SSL(不推荐)
public static SSLSocketFactory getSSLSocketFactory() {
try {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(
到了这里,关于Android - OkHttp 访问 https 的怪问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!