貨拉拉SSL證書踩坑之旅

語言: CN / TW / HK

一、背景簡介

1、遇到的問題

2020年,貨拉拉運營部門和客戶端開發對齊了https網路通訊協議中的SSL網路證書校驗方案;但是由於Android客戶端的證書配置不規範,導致在客戶端內建的SSL網路證書到期前十幾天被發現證書校驗異常,Android客戶端面臨全網訪問異常的問題

2、本文內容

本文主要介紹解決貨拉拉Android客戶端SSL證書到期的解決方案及Android端SSL證書相關知識

二、SSL證書簡介

1、SSL證書誕生背景

1994年,Netscape公司首先使用了SSL協議,SSL協議全稱為:安全套接層協議(Secure Sockets Layer),它指定了在應用程式協議(如HTTP、Telnet、FTP)和TCP/IP之間提供資料安全性分層的機制,它是在傳輸通訊協議(TCP/IP)上實現的一種安全協議,採用公開金鑰技術,它為TCP/IP連線提供資料加密、伺服器認證、訊息完整性以及可選的客戶端認證。由於SSL協議很好地解決了網際網路明文傳輸的不安全問題,很快得到了業界的支援,並已經成為國際標準

HyperText Transfer Protocol over Secure Socket Layer。在HTTPS中,使用傳輸層安全性(TLS)或安全套接字層(SSL)對通訊協議進行加密。也就是HTTP+SSL(TLS)=HTTPS

2、SSL證書簡介

按型別劃分,SSL證書包括CA證書、使用者證書兩種

(1)CA證書(Certification Authority證書頒發機構)

證書的簽發機構(CA)頒發的電子證書,包含根證書和中間證書兩種

[i]根證書

屬於根證書頒發機構(CA)的公鑰證書,是在公開金鑰基礎建設中,信任鏈的起點

一般客戶端會內建

[ii]中間證書

因為根證書太寶貴了,直接頒發風險太大了。因此,為了保護根證書,CAs通常會頒發所謂的中間證書。CA使用它的私鑰對中間證書籤名,使它受到信任。然後CA使用中間證書的私鑰簽署和頒發終端使用者SSL證書。這個過程可以執行多次,其中一箇中間根對另一箇中間根進行簽名

(2)使用者證書

使用者證書是由CA中間證書籤發給使用者的證書,包含伺服器證書、客戶端證書

[i]伺服器證書

組成Web伺服器的SSL安全功能的唯一的數字標識。 通過CA簽發,併為使用者提供驗證您Web站點身份的手段。

伺服器證書包含詳細的身份驗證資訊,如伺服器內容附屬的組織、頒發證書的組織以及稱為公開金鑰的唯一的身份驗證檔案

[ii]客戶端證書

在雙向https驗證中,就必須有客戶端證書,生成方式同伺服器證書一樣;

單向證書則不用生成

3、SSL證書鏈

SSL證書鏈是從使用者證書、生成使用者證書的CA中間證書、生成CA中間證書的CA中間證書...一直到CA根證書;其中根證書只能有一個,但是CA中間證書可以有多個

(1)以baidu的證書為例

(2)證書鏈

客戶端(比如瀏覽器或者Android手機)驗證我們SSL證書的有效性的時候,會一層層的去尋找頒發者的證書,直到自簽名的根證書,然後通過相應的公鑰再反過來驗證下一級的數字簽名的正確性

任何數字證書都必須要有根證書做支援,有了根證書的支援才說明這個數字證書是有效的是被信任的

4、SSL證書檔案的字尾

證書的字尾主要有.key、.csr、.crt、.pem等

(1).key檔案:金鑰檔案,SSL證書的私鑰就包含在其中

(2).csr檔案:這個檔案裡面包含著證書的公鑰和其他一些公司資訊,通過請求籤名之後就可以直接生出證書

(3).crt檔案:該檔案中也包含了證書的公鑰、簽名信息以及根據不同型別證書攜帶不同的認證資訊,如IP等(該檔案在有些機構、系統中也可能表現為.cert字尾)

(4).pem檔案:該檔案相對比較少見,裡面包含著證書的私鑰以及部分證書資訊

5、SSL使用者證書型別

SSL使用者證書主要分為(1)DV SSL證書 (2)OV SSL證書 (3)EV SSL證書

(1)DV SSL證書(域名驗證型):只需驗證域名所有權,無需人工驗證申請單位真實身份,幾分鐘就可頒發的SSL證書。價格一般在百元至千元左右,適用於個人或者小型網站

(2)OV SSL證書(企業驗證型):需要驗證域名所有權以及企業身份資訊,證明申請單位是一個合法存在的真實實體,一般在1~5個工作日頒發。價格一般在百元至幾千元左右,適用於企業型使用者申請

(3)EV SSL證書(擴充套件驗證型):除了需要驗證域名所有權以及企業身份資訊之外,還需要提交一下擴充套件型驗證,通常CA機構還會進行電話回訪,一般在2~7個工作日頒發證書。價格一般在千元至萬元左右,適用於線上交易網站、企業型網站

6、SSL證書結構

7、SSL證書檢視

以Chorme上的baidu為例:

第1步

第2步

第3步

三、客戶端SSL證書校驗流程

1、客戶端SSL證書校驗主要是在網路連線的SSL/TLS握手環節校驗

SSL/TLS握手(用非對稱加密的手段傳遞金鑰,然後用金鑰進行對稱加密傳遞資料)

校驗流程主要在上述過程的第三步和第六步

第三步:Certificate

Server——>Client 服務端下發公鑰證書

第六步:證書合法性校驗

Client 對 Server下發的公鑰證書進行合法性校驗

2、客戶端證書校驗過程

(1)校驗證書是否是受信任的CA根證書頒發機構頒發

客戶端通過伺服器證書 中籤發機構資訊,獲取到中間證書公鑰;利用中間證書公鑰進行伺服器證書的簽名驗證

a、中間證書公鑰解密 伺服器簽名,得到證書摘要資訊;

b、摘要演算法計算 伺服器證書 摘要資訊;

c、然後對比兩個摘要資訊。

客戶端通過中間證書中籤發機構資訊,客戶端本地查詢到根證書公鑰;利用根證書公鑰進行中間證書的簽名驗證

(2)客戶端校驗服務端證書公鑰及摘要資訊

客戶端獲取到服務端的公鑰:Https請求 TLS握手過程中,伺服器公鑰會下發到請求的客戶端。

客戶端用儲存在本地的CA機構的公鑰,對服務端公鑰中對應的摘要資訊進行解密,獲取到服務端公鑰的摘要資訊A;

客戶端根據對服務端公鑰進行摘要計算,得到摘要資訊B;

對比摘要資訊A與B,相同則證書驗證通過

(3)校驗證書是否在上級證書的吊銷列表

若證書的申請主體出現:私鑰丟失、申請證書無效等情況,CA機構需要廢棄該證書

(詳細策略見《四、Android端證書吊銷校驗策略》)

(4)校驗證書是否過期

校驗證書的有效期是否已經過期:主要判斷證書中Validity period欄位是否過期(ps:Android系統預設不校驗證書有效期,但瀏覽器和ios系統預設會校驗證書有效期)

(5)校驗證書域名是否一致

校驗證書域名是否一致:核查 證書域名是否與當前的訪問域名 匹配

比如:我們請求的域名 www.huolala.cn 是否與證書檔案DNS標籤下所列的域名匹配

四、Android端證書吊銷校驗策略

1、證書吊銷校驗主要存在兩類機制:CRL 與 OCSP

(1)證書吊銷列表校驗:CRL(Certificate Revocation List)

證書吊銷列表:是一個單獨的檔案,該檔案包含了 CA機構 已經吊銷的證書序列號與吊銷日期;

證書中一般會包含一個 URL 地址 CRL Distribution Point,通知使用者去哪裡下載對應的 CRL 以校驗證書是否吊銷。

該吊銷方式的優點是不需要頻繁更新,但是不能及時吊銷證書,這期間可能已經造成了極大損失

(2)證書狀態線上查詢:OCSP(Online Certificate Status Protocol)

證書狀態線上查詢協議:一個實時查詢證書是否吊銷的方式。

請求者傳送證書的資訊並請求查詢,伺服器返回正常、吊銷或未知中的任何一個狀態。

證書中一般也會包含一個 OCSP 的 URL 地址,要求查詢伺服器具有良好的效能。

部分 CA 或大部分的自籤 CA (根證書)都是未提供 CRL 或 OCSP 地址的,對於吊銷證書會是一件非常麻煩的事情

2、Android系統預設使用CRL方式來校驗證書是否被吊銷

核心實現類是CertBlocklistImpl(維護了本地黑名單列表),部分原始碼邏輯如下:

(1)TrustManagerImpl(證書校驗核心類)

第1步迴圈校驗信任證書

第2步檢查該證書是否在黑名單列表裡面

(2)CertBlocklistImpl(證書黑名單列表維護類)

黑名單校驗邏輯:主要檢查是否在黑名單列表裡面

黑名單本地儲存位置

可以看到黑名單檔案儲存在環境變數“ANDROID_DATA”/misc/keychain/pubkey_blacklist.txt;

可以通過adb shell--export--echo $ANDROID_DATA,拿到環境變數位置,一般在/data目錄下

3、Android端自定義證書吊銷校驗邏輯

核心類在TrustManagerFactory、CertPathTrustManagerParameters、PKIXRevocationChecker

(1)TrustManagerFactory工廠模式的證書管理類

有兩種init方式

[i]init(KeyStore ks) 預設使用

傳遞私鑰,一般傳遞系統預設或者傳空

以okhttp為例(預設傳空)

[ii]init(ManagerFactoryParameters spec) 自定義方式

下面介紹下通過自定義方式來實現OCSP方式校驗證書是否吊銷

4、基於PKIXRevocationChecker方式自定義OCSP方式

(1)自定義TrustManagerFactory.init(ManagerFactoryParameters spec)

init方法傳入基於CertPath的TrustManagerCertPathTrustManagerParameters,包裝策略PKIXRevocationChecker

(2)PKIXRevocationChecker(用於檢查PKIX演算法的證書撤銷狀態)

預設使用OCSP方式校驗,可以自定義使用OCSP策略還是CLR策略

參考谷歌開發者文件:http://developers.google.cn/j2objc/javadoc/jre/reference/java/security/cert/PKIXRevocationChecker

五、Android端證書校驗方式

主要有四種校驗方式:

客戶端單向認證服務端---證書鎖定

客戶端單向認證服務端---公鑰鎖定

客戶端服務端雙向認證

客戶端信任所有證書

1、客戶端單向認證服務端---證書鎖定

(1)校驗過程

校驗服務端證書的subject資訊和publickey資訊是否與客戶端內建證書一致,如果不一致會報錯:

“java.security.cert.CertPathValidatorException: Trust anchor for certification path not found”

(2)實現方式

[i]network-security-config配置方式

(生效範圍:app全域性,包含webview請求)

(只支援android7.0及以上)

[ii]程式碼配置方式(生效範圍:配置了該SSLParams的例項)

(3)優點

校驗了subject資訊和publickey資訊,防資訊篡改的安全等級高一點

(4)缺點

[i]因為一般網路證書的有效期是1-2年,所以面臨過期之後可能校驗異常的問題(ps:本次貨拉拉客戶端遇到的就是這種內建的網路證書快到期的case)

[ii]內建在app裡面,證書容易洩漏

2、客戶端單向認證服務端---公鑰鎖定

(1)校驗過程

校驗服務端證書的公鑰資訊是否與客戶端內建證書的一致

(2)實現方式

[i]network-security-config配置方式

(生效範圍:app全域性,包含webview請求)

(只支援android7.0及以上)

[ii]程式碼配置方式(生效範圍:配置了該引數的例項)

(3)優點

只要服務端的公鑰保持不變,更換證書也能通過校驗

(4)缺點

只校驗了公鑰,防資訊篡改的安全等級低一點

3、客戶端和服務端雙向認證

(1)實現方式

自定義的SSLSocketFactory實現客戶端和服務端雙向認證

``` public class SSLHelper {

/** * 儲存客戶端自己的金鑰 */  private final static String CLIENT_PRI_KEY = "client.bks";

/** * 儲存伺服器的公鑰 */  private final static String TRUSTSTORE_PUB_KEY = "publickey.bks";

/** * 讀取密碼 */  private final static String CLIENT_BKS_PASSWORD = "123321";

/** * 讀取密碼 */  private final static String PUCBLICKEY_BKS_PASSWORD = "123321";

private final static String KEYSTORE_TYPE = "BKS";

private final static String PROTOCOL_TYPE = "TLS";

private final static String CERTIFICATE_STANDARD = "X509";

public static SSLSocketFactory getSSLCertifcation(Context context) {

    SSLSocketFactory sslSocketFactory = null;

    try {
        // 伺服器端需要驗證的客戶端證書,其實就是客戶端的keystore
        KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE);
        // 客戶端信任的伺服器端證書
        KeyStore trustStore = KeyStore.getInstance(KEYSTORE_TYPE);

        //讀取證書
        InputStream ksIn = context.getAssets().open(CLIENT_PRI_KEY);
        InputStream tsIn = context.getAssets().open(TRUSTSTORE_PUB_KEY);

        //載入證書
        keyStore.load(ksIn, CLIENT_BKS_PASSWORD.toCharArray());
        trustStore.load(tsIn, PUCBLICKEY_BKS_PASSWORD.toCharArray());

        //關閉流
        ksIn.close();
        tsIn.close();

        //初始化SSLContext
        SSLContext sslContext = SSLContext.getInstance(PROTOCOL_TYPE);
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(CERTIFICATE_STANDARD);
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(CERTIFICATE_STANDARD);

        trustManagerFactory.init(trustStore);
        keyManagerFactory.init(keyStore, CLIENT_BKS_PASSWORD.toCharArray());

        sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
        sslSocketFactory = sslContext.getSocketFactory();
    } catch (KeyStoreException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (CertificateException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (UnrecoverableKeyException e) {
        e.printStackTrace();
    } catch (KeyManagementException e) {
        e.printStackTrace();
    }
    return sslSocketFactory;
}

} ```

(2)優點

雙向校驗更安全

(3)缺點

需要服務端支援,TLS/SSL握手耗時增長

4、客戶端信任所有證書

不檢驗任何證書,下面列兩種常見的實現方式

(1)OkHttp版本

(2)HttpURLConnection版本

六、Android端一種原始碼除錯的方式

背景:由於證書校驗相關原始碼不在Android.jar中,為了方便除錯證書校驗的流程,這裡簡單介紹一種非android.jar包中的Android原始碼除錯的方式

1、下載原始碼

(1)原始碼地址:http://android.googlesource.com/

android官方提供了各個模組的git倉庫地址

(2)以SSL證書除錯為例

我們只需要conscrypt部分的原始碼:http://android.googlesource.com/platform/external/conscrypt

注意點:選擇的分支要和被除錯的手機版本一致(因為不同系統版本下原始碼有點區別)

如果測試及時Android10.0系統,我們可以選擇android10-release分支

2、原始碼匯入

新建一個module 把剛才的系統原始碼複製進來,不需要依賴,只需要在setting.gradle中include,這樣做隔離性好,方便移除

3、原始碼編譯

匯入原始碼之後,可能會有部分編譯問題,可以解決的可以先解決,如果解決不了可以先註釋;

需要注意點:

(1)不能修改行號,否則除錯的時候走不到

(2)不能新增程式碼,新增的程式碼不會執行

4、斷點除錯

打好斷點就可以發車了

可以看到app發起網路請求之後會走到TrustManagerImpl裡面的checkServerTrusted校驗服務端證書

七、Android端證書校驗原始碼解析

1、證書校驗主要分3步

(1)握手過程中驗證證書

驗證證書合法性,判斷是否由合法的CA簽發,由上面的Android系統根證書庫來判斷

(2)驗證域名

判斷服務端證書是否為特定域名簽發,驗證網站身份,這裡如果出錯就會丟擲

SSLPeerUnverifiedException的異常

(3)驗證證書繫結

2、Android根證書相關原始碼

Android會內建常用的根證書,系統根證書存放在/system/etc/security/cacerts 目錄下,檔案均為 PEM 格式的 X509 證書格式,包含明文base64編碼公鑰,證書資訊,雜湊等

Android系統的根證書管理類

位於/frameworks/base/core/java/android/security/net/config 目錄下

以下是根證書管理類的類關係圖

(1)CertificateSource

介面類,定義了對根證書可執行的獲取和查詢操作

有三個實現類,分別是KeyStoreCertificateSource、ResourceCertificateSource、DirectoryCertificateSource

(2)KeyStoreCertificateSource

從 KeyStore 中獲取證書

(3)ResourceCertificateSource

基於 ResourceId 從資源目錄讀取檔案並構造證書

(4)DirectoryCertificateSource(抽象類)

遍歷指定的目錄 mDir 讀取證書;還提供了一個抽象方法 isCertMarkedAsRemoved() 用於判斷證書是否被移除

SystemCertificateSourceUserCertificateSource 繼承了DirectoryCertificateSource並且分別定義了系統和使用者根證書庫的路徑,並實現抽象方法

[i]SystemCertificateSource

定義了系統證書查詢路徑,並且還指定了被移除的證書檔案的目錄

判斷證書是否移除就是直接判斷證書檔案是否存在於指定的目錄

[ii]UserCertificateSource

定義了使用者證書指定查詢路徑,證書是否移除永遠為false

3、Android證書校驗原始碼

(以證書鎖定方式的單向校驗服務端證書為例)

核心類TrustManagerImpl、TrustedCertificateIndex、X500Principal

(1)第一步checkServerTrusted()

(2)第二步checkTrusted()

(3)第三步TrustedCertificateIndex類匹配證書issuer和signature資訊

private final Map> subjectToTrustAnchors

= new HashMap>();

可以看到獲取TrustAnchor是通過HashMap的key X500Principal匹配獲取的,

(4)X500Principal

private transient X500Name thisX500Name;

檢視X500Principal的原始碼可以看到它覆寫了equals()方法,對比的是屬性中的thisX500Name

除錯下來發現我們客戶端證書的 thisX500Name 的值為

“CN=*. huolala.cn , OU=IT, O=深圳貨拉拉科技有限公司, L=深圳市, ST=廣東省, C=CN”

(ps:後面會提到,貨拉拉客戶端證書異常主要因為新證書缺少了OU欄位)

(5)subject和issue資訊

八、貨拉拉SSL證書踩坑流程

1、背景簡介

2020年7月份的時候,貨拉拉出現了因為網路證書過期導致的異常,所以運維的同事拉了客戶端的同事一起對齊了方案,使用上述《客戶端單向認證服務端---公鑰鎖定》的方式

由於歷史原因:

貨拉拉使用者端使用了上述(三、1(2)客戶端單向認證服務端---證書鎖定,程式碼配置方式)

貨拉拉司機端使用了上述(三、1(1)客戶端單向認證服務端---證書鎖定,network-security-config配置方式)

2021年7月份的時候,運維同事更新了服務端的證書,因為更換過程中沒有出現異常,所以運維的同事以為android端都是按照之前約定的《客戶端單向認證服務端---公鑰鎖定》方式

(但實際原因是使用者和司機端提前內建了2022-8-19過期的證書)

2、線上出現異常

2022-8-1的時候,運維同事開始操作更新服務端2023年的證書,在更新了H5部分域名的證書之後,司機Android端出現部分網頁白屏的問題

排查之後發現服務端更新了證書導致客戶端證書校驗證書非法導致異常

2022-8-2的時候開始排查使用者端的邏輯,發現是《客戶端單向認證服務端---證書鎖定,程式碼配置方式》,測試之後發現

(1)刪除app內建2022年的證書,只保留2020年的證書之後,native請求異常,無法進入app

(2)手動調整手機裝置時間,發現native請求正常,webview白屏和圖片載入失敗

意味著在服務端更換的證書2022-8-19到期之後,客戶端將面臨全網訪問異常的問題

3、第一次嘗試解決

測試的時候發現,android端在證書過期時仍然可以訪問服務端(客戶端和服務端都保持一致的2022年的證書);

所以想的第1個解決方案是服務端仍然使用2022-8-19的證書,直到大部分使用者升級上來之後再更換新證書;

但是ios和web發現如果服務端使用過期證書的情況,系統底層會攔截這個過期證書直接報錯;

所以無法相容所有客戶端

4、第二次嘗試解決

在檢視原始碼TrustManagerImpl類原始碼的時候發現,TrustManagerImpl的服務端檢驗只是校驗了publickey(公鑰),所以如果2022年的舊證書和2023年的新證書如果公鑰一致的話,可能可以校驗通過;

所以想的第2個解決方案是服務端使用的新證書保持和2022-8-19的證書的公鑰一致就可以;

但是測試的時候發現native請求還是會報錯

“java.security.cert.CertPathValidatorException: Trust anchor for certification path not found”

5、第三次嘗試解決

開發發現按照證書鏈的校驗過程,如下:

如果有中間證書,那麼這個中間證書機構頒發的任何伺服器證書都可以都校驗通過;

所以想出的第3個解決方案是伺服器證書內建中間證書組成證書鏈;

但是排查之後發現伺服器證書和客戶端內建的證書裡面都已經包含了中間證書,所以依然行不通

(ps:如果客戶端內建的證書裡面刪除使用者證書資訊,只保留中間證書資訊,那麼只要是這家中間證書頒發的所有的伺服器證書都是可以校驗通過的,而且一般中間證書的有效期是10年,這也可以作為一個備選項,不過缺點是不安全)

6、第四次嘗試解決

(1)測試同學在網上找到一篇《那些年踩過HTTPS的坑(二)——APP證書鏈http://mp.weixin.qq.com/s/yv_XcMLvr8qRqaEJEQZiww》,發現android預設的校驗方式會校驗publickey公鑰+subject資訊(第一次看原始碼的時候漏掉了,原始碼除錯的時候才發現),對比之後發現是subject資訊不匹配,新證書缺少了OU(組織單位)欄位

所以想到的解決方案是重新申請一個帶OU欄位的新伺服器證書

(2)但是運維同事諮詢了兩家之前的中間商之後對方的回覆都是新的證書已經不再提供OU欄位,理由是

(3)最後歷經一言難盡的各種插曲最後找UniTrust頒發了帶OU欄位的新證書

(ps:還在使用證書鎖定方式校驗的可以留意下證書裡面的OU欄位,後續證書都不會再提供)

九、Android端證書校驗的解決方案

1、認證方式

按照安全等級劃分,從高到低依次為:

(1)客戶端和服務端雙向認證,參考上述《五、Android端證書校驗方式-3、客戶端和服務端雙向認證》

(2)客戶端單向認證服務端---證書鎖定,參考上述《五、Android端證書校驗方式-1、客戶端單向認證服務端---證書鎖定》

(3)客戶端單向認證服務端---公鑰鎖定,參考上述《五、Android端證書校驗方式-2、客戶端單向認證服務端---公鑰鎖定》

可以根據各自的安全需求選擇合適的認證方式

2、校驗方式

(1)證書校驗

具體方式參考《五、Android端證書校驗方式-1、客戶端單向認證服務端---證書鎖定》;

為了增強安全性,app可以內建加密後的證書,將解密資訊存放在加固後的c++端,增強安全性

(2)公鑰校驗

具體方式參考《五、Android端證書校驗方式-2、客戶端單向認證服務端---公鑰鎖定》;

為了增強安全性,app可以內建加密後的公鑰,將解密資訊存放在加固後的c++端,增強安全性

3、配置降級

為了在出現異常情況時不影響app訪問,可以新增動態配置和動態降級能力

(1)動態配置

動態下發公鑰和證書資訊,需要留意下發的時機要儘量早一點,避免證書異常時走不到下發的請求

(2)動態降級

動態降級證書校驗功能,在客戶端證書或者服務端證書出現異常時,支援動態關閉所有的證書校驗的功能

十、總結

最後,總結一下整體的思路:

1、SSL證書分為CA證書和使用者證書

2、客戶端SSL證書校驗是在網路連線的SSL/TLS握手環節進行校驗

3、SSL證書的認證方式分為(1)單向認證(2)雙向認證

4、SSL證書的校驗方式分為(1)證書校驗(2)公鑰校驗

5、SSL證書的校驗流程主要是校驗證書是否是由受信任的CA機構簽發的合法證書

6、SSL證書的吊銷校驗策略分為(1)CRL本地校驗證書吊銷列表(2)OCSP證書狀態線上查詢

7、縱觀本次踩坑之旅,也暴露出一個比較深刻的問題:大部分的客戶端開發的認知還是停留在app上層,缺少對底層技術的認識和探索,導致一個很小的配置問題差點釀成大的事故;這也為想在客戶端領域進一步提升提供了一個思路:多學習客戶端的底層技術,包含網路底層實現、安全、系統底層原始碼等等

8、最後,解決技術類問題最核心的點還是學習和熟悉原始碼;解決證書配置問題的過程中,走了不少彎路,本質上是最開始沒有徹底掌握證書校驗相關的系統原始碼的邏輯,客觀上是由於缺少非android.jar原始碼的除錯手段導致閱讀原始碼遺漏了部分校驗邏輯,所以本次特意補上(六、Android端一種原始碼除錯的方式),希望後續遇到系統級的疑難雜症可以用的上

參考:

http://www.cnblogs.com/xiaxveliang/p/13183175.html

http://blog.csdn.net/weixin_35016347/article/details/105802480