あらすじ
Windows上でAndroidエミュレータを動かしてアプリ通信を監視できる環境を作ろうと思ったものの、Android 7.0以降ではSSL通信をキャプチャするための証明書のインストールが前よりも複雑になっていたのでメモ。
検証環境
- Androidエミュレータ (7.0.1.6)
基本なんでも大丈夫ですが、今回はPythonでごにょごにょできるらしいNoxPlayerを使用。 - Charles (4.6.2)
今回はCharlesを使いましたがお好みで大丈夫です。 - Windows10 (ホストPC)
Windows側でやっておくこと
証明書のインストール
まずはWindowsにCharlesの証明書をインストールします。
Charlesを起動してメニューの Help > SSL Proxying > Install Charles Root Certificate を選択

続けて開いた証明書をインポートウィザードに従ってインストールします。
Noxでadbを使えるようにしておく
Noxをインストールした場所にある「bin」フォルダをシステム環境変数のPathに追加します。
自分の場合は以下のパスで追加しました。
D:\Program Files\Nox\bin

opensslコマンドが使えるようにしておく
証明書の変換を行う際にopensslコマンドを使用するため以下からインストールしておきます。
https://slproweb.com/products/Win32OpenSSL.html
ホストであるWindowsのIPアドレスを確認しておく
コマンドプロンプトにて「ipconfig」コマンドを実行し、結果のIPv4アドレスを控えておきます。
エミュレータ側でやっておくこと
WiFiの接続詳細設定にてProxyの設定を行います。
控えたホストPCのIPアドレスとCharlesで使用されるデフォルトのポート8888番を入力し、設定を保存します。

次にブラウザ上で http://chls.pro/ssl を開きCharlesの証明書をダウンロードしておきます。
証明書をシステム証明書としてインストールできる形式に変換
Noxのインストールディレクトリにある「bin」フォルダ内でコマンドプロンプトを起動し
adb pullコマンドでダウンロードした証明書を一度PC側に保存します。
adb pull /storage/emulated/0/Download/downloadfile.crt ./downloadfile.crt
デフォルトの形式はcrtなのでまずはopensslコマンドでDER形式に変換します。
openssl x509 -in downloadfile.crt -out tmp.der -outform DER
次に以下のコマンドで変換したDERをさらにPEMに変換します。
openssl x509 -in tmp.der -inform DER -out cacert.pem -outform pem
変換した証明書のsubject_hashを以下のコマンドで確認します。先頭行の英数字を控えます。
openssl x509 -inform PEM -subject_hash_old -in cacert.pem

出力結果を見るとsubject_hashは「8cf8e6ab」なので、これを使ってシステム証明書として読み取れる以下の形式にファイル名を変更します。
subject_hash + .0
つまり今回の場合は以下のコマンドでファイル名を変更します。
ren cacert.pem 8cf8e6ab.0
これで必要なシステム証明書が出来上がりました。
作成した証明書をインストール
出来上がったので証明書をadbを使ってエミュレーター側に転送します。
adb push 8cf8e6ab.0 /sdcard/8cf8e6ab.0
証明書のインストールを行うためシェルに入ります。
adb shell
インストール先のsystemフォルダに書き込みができるようにマウントしておきます。
mount -o rw,remount /system
出来上がった証明書をシステム証明書として設置します。
mv /sdcard/8cf8e6ab.0 /system/etc/security/cacerts/8cf8e6ab.0
設置した証明書ファイルの権限を変更します。
chmod 644 /system/etc/security/cacerts/8cf8e6ab.0
最後にエミュレーターを再起動します。
reboot
CharlesでアプリのSSL通信をキャプチャしてみる
実際にSSL通信が行われているアプリを起動してリクエストを送ってみます。
以下のように通信内容が確認できる状態になっていれば成功です!お疲れ様でした。
