一、先擺出問(wèn)題:
如題,今天遇到了一個(gè)安卓手機(jī)無(wú)法抓取 https 請(qǐng)求的問(wèn)題,提示:Client SSL handshake failed: An unknown issue occurred processing the certificate(certificate_unknown)

于是我重新檢查了一下環(huán)境配置:
- 1. 小米安卓手機(jī)與 mac 筆記本連接的是同一個(gè)網(wǎng)絡(luò);
- 2. mac 筆記本已經(jīng)通過(guò) Charles Help ---> SSL Proxying ---> Install Charles Root Certificate 安裝了 Charles 證書(shū),并且通過(guò)鑰匙串已設(shè)置完全信任該證書(shū),如下圖所示: 01charles證書(shū)信任.png
- 3. 小米安卓手機(jī)網(wǎng)絡(luò)設(shè)置已設(shè)置代理,代理的ip確認(rèn)是mac 筆記本的 ip,同時(shí)端口號(hào)已設(shè)置8888
- 4. 小米安卓手機(jī)通過(guò)谷歌瀏覽器訪問(wèn) http://chls.pro/ssl 鏈接,成功下載到證書(shū),并按照手機(jī)的提示將證書(shū)名稱改為 1.crt 。點(diǎn)確定后,手機(jī)提示成功安裝該證書(shū)。
- 5. 通過(guò)手機(jī)系統(tǒng)設(shè)置 ---> 更多設(shè)置 ---> 系統(tǒng)安全 ---> 已信任的憑據(jù)信息 ---> 用戶 界面中,能看到 charles 證書(shū)確實(shí)已成功安裝。
排查了一圈,沒(méi)發(fā)現(xiàn)哪里有問(wèn)題。要是換作是 iOS(操作步驟跟上面的大同小異),都到這一步了肯定是沒(méi)問(wèn)題的。我重新打開(kāi) 安卓的 app 再嘗試抓包,發(fā)現(xiàn)還是不行。于是我重啟了安卓手機(jī),再嘗試抓包,還是不行。摸不著頭腦的我只能開(kāi)始在網(wǎng)上尋找答案。
二、后面終于找到了解決方案:
前提:在手機(jī)端和電腦端都必須安裝 https 的安全證書(shū);
配置:打測(cè)試包時(shí),項(xiàng)目設(shè)置默認(rèn)信任所有證書(shū)(系統(tǒng)+用戶)
(1) 在工程 res-xml 目錄中創(chuàng)建一個(gè)名為 network_security_config.xml 的文件,文件內(nèi)容如下:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" overridePins="true" />
<certificates src="user" overridePins="true" />
</trust-anchors>
</base-config>
</network-security-config>
(2) 在 AndroidManifest 里的標(biāo)簽中,添加如下代碼:
android:networkSecurityConfig="@xml/network_security_config"
重新打包項(xiàng)目,然后抓包,即成功了。
你以為到這就結(jié)束了?然而并沒(méi)有。
三、我還是有個(gè)疑問(wèn),上面的例子只適合能夠修改源碼并能重新打包或者是真機(jī)調(diào)試的情況。如果是之前已經(jīng)打好的包突然某個(gè)接口網(wǎng)絡(luò)請(qǐng)求出問(wèn)題只能采取抓包的方式來(lái)解決,并且之前并沒(méi)有添加上面的代碼的情況,那又該怎么呢?
接下來(lái)要敲重點(diǎn)了:Android 7.0及7.0以上的機(jī)子改變了安全策略,默認(rèn)不信任用戶添加到系統(tǒng)的 CA 證書(shū):
To provide a more consistent and more security experience accross the Android ecosystem,beginning with Android Nougat, compatible devices trust only the standardized system CAs maintained in AOSP.
翻譯:
為了在Android生態(tài)系統(tǒng)中提供更一致、更安全的體驗(yàn),從Android Nougat開(kāi)始,兼容設(shè)備只信任AOSP中維護(hù)的標(biāo)準(zhǔn)化系統(tǒng)CA。
也就是說(shuō)對(duì)基于 SDK24 及以上的 App 來(lái)說(shuō),即使你在手機(jī)上安裝了抓包工具的證書(shū)也無(wú)法抓取 https 請(qǐng)求。
解決方案:
將抓包工具的證書(shū)添加到系統(tǒng)證書(shū)中!效果如下圖所示:

實(shí)踐步驟:
- 需要先獲取你的安卓測(cè)試機(jī) root 權(quán)限。我用的是紅米手機(jī),獲取 root 權(quán)限操作如下:設(shè)置 ---> 授權(quán)管理 --> 開(kāi)啟ROOT權(quán)限 即可。之后手機(jī)會(huì)重啟,重啟之后即可成功 root 。
- 通過(guò) 電腦端的 Charles 拿到后續(xù)要安裝到手機(jī)上的證書(shū),并通過(guò) openssl x509 -subject_hash_old -in 命令計(jì)算出它的哈希值。并將證書(shū)重命名為 哈希值.0 或者哈希值.1 。
-
獲取證書(shū)的哈希值,如下圖所示:image.png
- 命令如下:
openssl x509 -subject_hash_old -in
-
通過(guò) 電腦端的 Charles 拿到后續(xù)要安裝到手機(jī)上的證書(shū)步驟也很簡(jiǎn)單:
Charles 菜單欄 ---> Help ---> SSL Proxying ---> Save Charles Root Certificate。選擇要保存的路徑即可。如下圖所示:
通過(guò) 電腦端的 Charles 拿到后續(xù)要安裝到手機(jī)上的證書(shū).png - 證書(shū)重命名如下圖所示:證書(shū)重命名.png
注意:這一步必須保證證書(shū)沒(méi)有隱藏后綴名,可以點(diǎn)右鍵,顯示簡(jiǎn)介,將隱藏后綴名的勾去掉。將后綴名置為1或者0 。系統(tǒng)會(huì)提示你是否確認(rèn)使用該后綴,點(diǎn)確定即可。
- root 成功的安卓測(cè)試機(jī)連接電腦。我這里用是 mac 筆記本。接下來(lái)是mac 通過(guò)終端來(lái)操作:
- 打開(kāi)終端,通過(guò)終端將當(dāng)前的工作目錄切換到第二步保存證書(shū)的所在目錄,我這里是將證書(shū)直接保存到家目錄下的 Download 目錄下。所以切換工作目錄的命令如下:
cd /Users/pilipala/Downloads; clear; pwd
安卓系統(tǒng)的安全證書(shū)是在 /system/etc/security/cacerts 目錄下的,終端輸入 adb shell ,打開(kāi)目錄就能看到這些證書(shū),如下圖所示:
我們最終目標(biāo)是要將安裝到手機(jī)端的證書(shū)添加到該目錄下。而在這之前,我們得先將證書(shū)發(fā)送到手機(jī)端的 sdcard 的 Download 目錄,再將證書(shū)從手機(jī)端的 sdcard 的 Download 目錄復(fù)制到安卓系統(tǒng)的安全證書(shū)目錄。
接著輸入 adb push 命令將證書(shū)推給手機(jī)端的 sdcard 的 Download 目錄。命令如下:
adb push f050a275.1 /sdcard/Download
注意看終端的提示,此時(shí)終端很快會(huì)提示你有一個(gè)文件被 pushed,即 push 成功。如下圖所示:
- 這一步很關(guān)鍵,需要將 /sdcard/Download 目錄下的證書(shū)復(fù)制到系統(tǒng)證書(shū)的所在目錄。命令如下:
cp /sdcard/Download/f050a275.1 /system/etc/security/cacerts/
然而我復(fù)制的時(shí)候提示我證書(shū)是一個(gè) ReadOnly 文件。如下圖所示:
我通過(guò)測(cè)試,發(fā)現(xiàn)關(guān)閉手機(jī)安全驗(yàn)證機(jī)制的方案是可以解決的,命令如下:
adb root
adb disable-verity
adb reboot //此時(shí)手機(jī)會(huì)重啟,這時(shí)候不要拔插數(shù)據(jù)線
手機(jī)重啟后,再次執(zhí)行上面的 cp 命令,如果終端沒(méi)有任何提示,即復(fù)制成功,看到勝利的曙光了。
- 接著,賦予證書(shū)執(zhí)行的權(quán)限。
chmod 644 /system/etc/security/cacerts/f050a275.1
- 最后重啟手機(jī)即可。
到這里,再打開(kāi)手機(jī)設(shè)置 --> 更多設(shè)置 --> 系統(tǒng)安全 --> 信任的憑據(jù) --> 系統(tǒng),就能看到抓包工具的證書(shū)已經(jīng)被我們成功添加進(jìn)來(lái)了。默認(rèn)是開(kāi)啟信任的。如果沒(méi)有,打開(kāi)信任即可。
再重新抓包,就能發(fā)現(xiàn) https 的請(qǐng)求也能抓取到了。
四、寫(xiě)在最后
- 證書(shū)重命名那一塊,一般會(huì)將證書(shū)重命名為:哈希值.0,如果安卓系統(tǒng)的安全證書(shū)目錄下已經(jīng)存在相同哈希值的證書(shū),可以將證書(shū)的后綴名重命名為 .1 。再將證書(shū)復(fù)制到安卓系統(tǒng)的安全證書(shū)目錄下。
- 其他品牌的手機(jī)(如 vivo等)我沒(méi)試過(guò),不過(guò)操作步驟應(yīng)該是差不多的。
以上,感謝閱讀!



