遇到的问题
由于 Android7 以后 google 更改了安全策略, 用户添加的 CA 证书不能再用于安全连接, 意思就是你自己安装的 Charles 的证书也没有卵用了. 当我们抓 HTTPS 的包时候会出现下面的问题
设备上伴随会出现下面的 log
- 2019-02-11 14:27:12.232 8913-8954/? W/System.err: javax.NET.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
- 2019-02-11 14:27:12.232 8913-8954/? W/System.err: at com.Android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:361)
- 2019-02-11 14:27:12.232 8913-8954/? W/System.err: at com.Android.okhttp.Connection.connectTls(Connection.java:235)
- 2019-02-11 14:27:12.232 8913-8954/? W/System.err: at com.Android.okhttp.Connection.connectSocket(Connection.java:199)
- 2019-02-11 14:27:12.233 8913-8954/? W/System.err: at com.Android.okhttp.Connection.connect(Connection.java:172)
- 2019-02-11 14:27:12.233 8913-8954/? W/System.err: at com.Android.okhttp.Connection.connectAndSetOwner(Connection.java:367)
- 2019-02-11 14:27:12.233 8913-8954/? W/System.err: at com.Android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:130)
- 2019-02-11 14:27:12.233 8913-8954/? W/System.err: at com.Android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:329)
- 2019-02-11 14:27:12.233 8913-8954/? W/System.err: at com.Android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:246)
- 2019-02-11 14:27:12.233 8913-8954/? W/System.err: at com.Android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:457)
- 2019-02-11 14:27:12.233 8913-8954/? W/System.err: at com.Android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:126)
- 2019-02-11 14:27:12.233 8913-8954/? W/System.err: at com.Android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:89)
- 2019-02-11 14:27:12.233 8913-8954/? W/System.err: at com.Android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java)
- 2019-02-11 14:27:12.233 8913-8954/? W/System.err: at com.growingio.Android.sdk.gtouch.http.HttpRequest.execute(HttpRequest.java:73)
- 2019-02-11 14:27:12.233 8913-8954/? W/System.err: at com.growingio.Android.sdk.gtouch.http.HttpRequest$1.run(HttpRequest.java:110)
- 2019-02-11 14:27:12.233 8913-8954/? W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
- 2019-02-11 14:27:12.233 8913-8954/? W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
- 2019-02-11 14:27:12.233 8913-8954/? W/System.err: at java.lang.Thread.run(Thread.java:761)
- 2019-02-11 14:27:12.235 8913-8954/? W/System.err: Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
- 2019-02-11 14:27:12.235 8913-8954/? W/System.err: at com.Android.org.conscrypt.TrustManagerImpl.verifyChain(TrustManagerImpl.java:563)
- 2019-02-11 14:27:12.235 8913-8954/? W/System.err: at com.Android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:444)
- 2019-02-11 14:27:12.235 8913-8954/? W/System.err: at com.Android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:508)
- 2019-02-11 14:27:12.235 8913-8954/? W/System.err: at com.Android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:401)
- 2019-02-11 14:27:12.235 8913-8954/? W/System.err: at com.Android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:375)
- 2019-02-11 14:27:12.235 8913-8954/? W/System.err: at com.Android.org.conscrypt.TrustManagerImpl.getTrustedChainForServer(TrustManagerImpl.java:304)
- 2019-02-11 14:27:12.235 8913-8954/? W/System.err: at Android.security.NET.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:94)
- 2019-02-11 14:27:12.235 8913-8954/? W/System.err: at Android.security.NET.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:88)
- 2019-02-11 14:27:12.236 8913-8954/? W/System.err: at com.Android.org.conscrypt.Platform.checkServerTrusted(Platform.java:178)
- 2019-02-11 14:27:12.236 8913-8954/? W/System.err: at com.Android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:596)
- 2019-02-11 14:27:12.236 8913-8954/? W/System.err: at com.Android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
- 2019-02-11 14:27:12.236 8913-8954/? W/System.err: at com.Android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
- 2019-02-11 14:27:12.236 8913-8954/? W/System.err: ... 16 more
- 2019-02-11 14:27:12.236 8913-8954/? W/System.err: Caused by: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
- 2019-02-11 14:27:12.236 8913-8954/? W/System.err: ... 28 more
解决办法一
该方法针对未 Root 的设备, 直接参看 Android 官方的文档 但是这个办法有个局限就是只能抓取自己 App 的包, 无法抓取第三方 App, 而且操作麻烦.
解决办法二
本文章主要讲的是该方法, 一个一劳永逸的方法, 就是将 Charles 的证书安装为系统证书.
1. 确保手机已经 Root
至于 Root 的方法我就不再累述
2. 下载证书
根据 Charles 的 help 浏览 chls.pro/ssl 下载证书, 你可以在设备上下载后 adb pull 到电脑上, 也可以直接用电脑浏览器下载.
3. 重命名证书
系统证书在目录 / system/etc/security/cacerts / 下, 我们看到
其中的每个证书的命名规则是
<Certificate_Hash>.<Number>
, 文件名是一个 Hash 值, 而后缀是一个数字. 后缀名的数字是为了防止文件名冲突的, 比如如果两个证书算出的 Hash 值是一样的话, 那么一个证书的后缀名数字可以设置成 0, 而另一个证书的后缀名数字可以设置成 1.
我们用下面的命令计算出证书文件的 Hash 值 openssl x509 -subject_hash_old -in <Certificate_File>
4. 上传证书
我们将重命名好的证书 adb push 到 / sdcard/Download, 然后将其复制到 / system/etc/security/cacerts / 文件夹.
如果出现上面问题, 那么我们就需要使用
mount -o rw,remount /system
命令将 system 分区挂在为可读写. 复制好后将文件权限更改为 644, 并重启设备
5. 验证结果
设置》安全》信任的凭证, 我们可以看到
HTTPS 抓包我们可以看到
来源: https://juejin.im/post/5c611302f265da2ddc3c5622