一、簡(jiǎn)述
最近使用 OkHttp 訪問(wèn) https 請(qǐng)求時(shí),在個(gè)別 Android 設(shè)備上遇到了幾個(gè)問(wèn)題,搜羅網(wǎng)上資料,經(jīng)過(guò)一番實(shí)踐后,問(wèn)題得到了解決,同時(shí),我也同步升級(jí)了我的 https 證書忽略庫(kù) ANoSSL ,在此,對(duì)搜集到的資料和問(wèn)題解決方案做個(gè)記錄。
文章中的代碼實(shí)現(xiàn)可到 GitHub 倉(cāng)庫(kù)中自行獲取:
- https://github.com/GitLqr/ANoSSL
二、協(xié)議
要想讓 OkHttp 支持 https 請(qǐng)求,需要先對(duì) https 證書協(xié)議以及 OkHttp 的支持情況有個(gè)大概了解:
- 【服務(wù)端】https 證書是配置在服務(wù)端的,大體分為
SSL
和TLS
兩種協(xié)議,TLS (Transport Layer Security) 是 SSL 的升級(jí)版本,可以修復(fù)現(xiàn)有的 SSL 漏洞。 - 【客戶端】OkHttp 支持過(guò)的 https 證書協(xié)議有 SSLv3 (1996)、TLSv1 (1999)、TLSv1.1 (2006)、TLSv1.2 (2008) 和 TLSv1.3 (2018),但要注意,OkHttp 從 2014 年開始就放棄對(duì)
SSLv3
支持,2019 年(3.13.x)開始放棄對(duì)TLSv1
和TLSv1.1
的支持,以TLSv1.2
為最低支持標(biāo)準(zhǔn)。
資料來(lái)源:
- 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
我找了幾個(gè)網(wǎng)站,它們支持的 https 證書協(xié)議支持情況如下:
支持協(xié)議 | 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 |
數(shù)據(jù)來(lái)源:
- https://www.ssleye.com/ssltool/cipher_suites.html
- https://www.ssllabs.com/ssltest/
可以看到,這幾個(gè)網(wǎng)站都支持 TLS1.2
,而對(duì)于其他的 ssl 協(xié)議的支持力度各不相同,目前來(lái)說(shuō),TLS1.2
才是主流,但有可能存在個(gè)別網(wǎng)站不支持,所以,我們?cè)谑褂?OkHttp 發(fā)起 https 請(qǐng)求之前,首先要搞清楚,就是服務(wù)端(接口)支持的 ssl 協(xié)議有哪些。確認(rèn)好服務(wù)端的 ssl 協(xié)議支持情況后,就可以開始配置客戶端的 OkHttp 了。
三、配置
這里有個(gè)問(wèn)題,是否只要發(fā)送 https 請(qǐng)求,就一定需要給 OkHttp 配置 https 校驗(yàn)?zāi)??答案是非必須的,正常情況下 OkHttp 會(huì)使用默認(rèn)的系統(tǒng)配置,用于訪問(wèn)一般的 https 請(qǐng)求足以,但往往有一些特殊情況,就需要我們?cè)诠こ讨羞M(jìn)行單獨(dú)配置并實(shí)現(xiàn)校驗(yàn)規(guī)則,例如以下幾種情況:
- 服務(wù)端使用了非 CA 認(rèn)證的私有 https 證書
- 服務(wù)端使用了過(guò)期的 https 證書
- 客戶端支持某個(gè) ssl 協(xié)議但是默認(rèn)沒有啟用
好了,下面開始對(duì) OkHttp 進(jìn)行配置,大體分兩步:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-861801.html
- 配置
SSLSocketFactory
:用于指定支持某種 ssl 協(xié)議的 SocketFactory - 配置
HostnameVerifier
:用于檢查證書中的主機(jī)名與使用該證書的服務(wù)器的主機(jī)名是否一致
val sslSocketFactory = NoSSLSocketClient.getTLSSocketFactory()
val x509TrustManager = NoSSLSocketClient.getX509TrustManager()
val hostnameVerifier = NoSSLSocketClient.getHostnameVerifier()
val okHttpClient = OkHttpClient.Builder()
.sslSocketFactory(
sslSocketFactory,
x509TrustManager // 必須指定該參數(shù),否則 Android 10 及以上版本會(huì)閃退
)
.hostnameVerifier(hostnameVerifier)
.build()
這里主要看 sslSocketFactory 是怎么創(chuàng)建的,前面說(shuō)過(guò),https 證書大體分為 SSL
和 TLS
兩種協(xié)議,這里的 SSLSocketFactory
也一樣,以下是兩種協(xié)議對(duì)應(yīng)的創(chuàng)建方式,它們僅僅只是在獲取 SSLContext
實(shí)例時(shí)傳的參數(shù)不同而已:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-861801.html
// SSL(不推薦)
public static SSLSocketFactory getSSLSocketFactory() {
try {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(
到了這里,關(guān)于Android - OkHttp 訪問(wèn) https 的怪問(wèn)題的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!