這篇筆記紀錄如何解析 Android APP 的自定義 rootCA 白名單,也就是 CA pinning。本來還有 iOS 的部分,但就連撰寫 iOS App 的同事都不知道究竟是如何編碼,自己花了一些時間也始終看不懂,所以就先不寫了。

會有這篇筆記的原由:買了 Cloudflare,但 app 內因為「資安合規」音速,設定了 CA pinning。

AWS 使用的 rootCA 清單: Amazon Trust Services Repository

CloudFlare 使用的 Google Trust rootCA 清單: Google Trust Services | Repository

Android [ref]

放在 res/xml/network_security_config.xml 當中,範例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">xxx.com</domain>
        <domain includeSubdomains="true">bbb.com</domain>
        <pin-set>
            <pin digest="SHA-256">++MBgDH5WGvL9Bcn5Be30cRcL0f5O+NyoXuWtQdX1aI=</pin>
            <pin digest="SHA-256">f0KW/FtqTjs108NpYj42SrGvOB2PpxIVM8nWxjPqJGE=</pin>
            <pin digest="SHA-256">NqvDJlas/GRcYbcWE8S/IceH9cq77kg0jVhZeAPXq8k=</pin>
            <pin digest="SHA-256">9+ze1cZgR9KO1kZrVDxA4HQ6voHRCSVNz4RdTCx4U8U=</pin>
            <pin digest="SHA-256">KwccWaCgrnaw6tsrrSO61FgLacNgG2MMLq8GE6+oP5I=</pin>
        </pin-set>
    </domain-config>
</network-security-config>
  • <domain includeSubdomains="true">xxx.com</domain>: 這裡定義了受信任的網域名稱,includeSubdomains="true" 表示該網域及其所有子網域都受信任。

pin digest="SHA-256" 如何產生?

1
2
3
4
5
# RSA
openssl x509 -in ~/Downloads/AmazonRootCA1.pem -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

# EDCSA
openssl x509 -in ~/Downloads/gsr4.pem -pubkey -noout | openssl ec -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

參考資料