アプリのデバッグ時にCharlesでHTTPSトラフィックを解析したいけど証明書が入れられない問題
Androidアプリを作る上で、CharlesによるHTTPSのトラフィック解析には大いに助けられていると思います。
さて、CharlesでHTTPSトラフィックを解析するためにはCharlesが発行した独自証明書をAndroidの証明書ストアに登録する必要がありますが、一部のAndroid端末(たとえば一部のAndroidTVなど)では証明書ストアへの独自証明書のインストールを許可していないものもあります。
Android 7.0以降限定の手法とはなりますが、そのようなAndroid端末でもアプリデバッグ時にCharlesでHTTPSを解析できるようにする方法を見つけたので記します。
手法の概要
Android 7.0からネットワークセキュリティーの仕様が変わり、マニフェストで明示的にトラストストアを指定するようになりました。
この機能を活用して、『デバッグ版アプリ内にRAWリソースとして埋め込んだCharlesが発行した独自証明書を信頼する』という設定を入れることで、デバッグ時だけCharlesでHTTPSトラフィックを閲覧できます。
具体的な手法
(1) Charlesの証明書をデバッグ時にだけアプリに埋め込む
まず、Build Variantsを利用し、デバッグビルド版アプリのリソース内にだけCharlesの証明書を埋め込みます。
Charlesを立ち上げ、メニューから[Help]>[SSL Proxying]>[Save Charles Root Certificate]と選び、Charlesの証明書(PEM形式)を任意の場所に保存しておきます。
次に、Android Studio内の次のようなパスにそのPEMファイルを設置することで、RawリソースとしてDebugビルドにのみ埋め込みます。
※Rawリソースにはファイル名の制限があるので、先の手順で保存したPEMファイルの拡張子などを取っ払って「charles_ca_pem」という名前にし、rawディレクトリ内に移動するだけです。
(2) 埋め込んだ証明書をデバッグ時に参照し信頼する設定を入れる
<network-security-config>
の<debug-overrides>
を利用することで、デバッグ時のみ埋め込んだ独自証明書を参照&信頼するという設定が行えます。
この設定はデバッグ時のみ有効で、かつ、Playストアにはデバッグ可能なアプリは公開できないので、本番リリース版アプリで意図せずCharlesでHTTPSトラフィックが覗けてしまうという事態を防ぐことができます。
debugなBuild Variantsで次のように書くと、RAWリソース内の証明書を参照しそれを信頼する証明書としてトラストアンカーに追加することができます。
debug/res/xml/network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<debug-overrides>
<trust-anchors>
<certificates src="@raw/charles_ca_pem"/>
</trust-anchors>
</debug-overrides>
</network-security-config>
ストア公開版のmainバリアントの方のnetwork_security_configはとりあえず空で作っておきます。
main/res/xml/network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
</network-security-config>
あとは、これらnetwork_security_config.xmlをAndroidManifest.xmlから参照することで、証明書信頼設定がこのアプリで有効になります。
<application
android:name=".MyApp"
android:networkSecurityConfig="@xml/network_security_config"
>
...
</application>
アプリ側での準備はこれだけです。
あとはAndroidのプロキシ設定画面でCharlesを利用するようにすれば、CharlesでアプリのHTTPSトラフィックが見えるようになっていると思います。