Android emulator に Charles proxy の Root Ceartificate をインストールして SSL/TLS 通信をのぞき見する(on Mac)

Charles は Flashアプリケーションを作っていた開発者が、アプリケーションから利用するHTTP通信のデバッグを行うために作ったプロキシーです。

参考:

niwatako.hatenablog.jp

Flashにとどまらず、ブラウザやiOS, Android端末にCharlesで用意したプロキシーサーバーを設定することで、アプリケーションがAPIとどのような通信を行っているか確認したり、APIのレスポンスを書き換えてアプリケーションの挙動を確認したりすることが出来ます。

MaciOSでCharlesプロキシを利用するのは、Charlesの標準機能で支援されていますが、Androidは手動でやらなくてはならなかったのでその手順のメモです。

環境は macOS High Sierra, Android 8.1 Emulator です。

Charles でプロキシーを有効にする

Charles でプロキシーを起動する。 ( Proxy > Proxy Settings... )

f:id:niwatako:20180620111414p:plain

Emulatorに設定すべきプロキシの情報、Certificate取得用のURLを確認する。 ( Help > SSL Proxying > Install Chales Root Certificate on a Mobile Device or Remote Browser )

f:id:niwatako:20180620111638p:plain

Emulatorをプロキシーを有効にして起動する

上記で最後に確認した情報をもとに、コマンドラインから -http-proxy http://IP:PORT を渡してEmulatorを起動するとプロキシーが有効になる。

niwatako の部分は適宜自身のユーザー名に読み替えてください。

niwatako$ /Users/niwatako/Library/Android/sdk/emulator/emulator -netdelay none -netspeed full -avd Nexus_S_API_27 -http-proxy http://172.21.21.204:8888

ちなみに -avd のあとに渡す Android Virtual Deviceの名前 (上記では Nexus_S_API_27 ) は、Android Studio のDevice Managerから確認できる。

f:id:niwatako:20180620113444p:plain

f:id:niwatako:20180620113452p:plain

あるいは

niwatako$ /Users/niwatako/Library/Android/sdk/emulator/emulator -list-avds

でavdを一覧できる。

Emulatorで実際に通信しようとするとCharles側にProxyとの接続を許可するかどうか問うダイアログが出るので、 Allow する。

http でプロキシを使いたいだけならこれで完了。

※ 追記: GUIからも設定できるんですね Using the emulator with a proxy

https で Charles Proxy を利用するようにする

https でもプロキシを使いたければ、まず Charles でSSLロキシーを有効にする ( Proxy > SSL Proxying Settings )。

Enable SSL Proxying にチェックを入れ、Addから対象にしたい条件を追加。とりあえず全部有効にしたければ Host: *, Port: * にする。

この状態で https:// の適当なサイトに接続すると、証明書のエラーが出る。サイトの正規の証明書を使ってCharlesが通信し、CharlesとEmulatorはCharlesが用意した証明書で通信しようとしている。デバイスはCharlesの証明書を信用して良いものと製造時に教わっていないので、エラーが出る状態。

この状態でEmulatorのブラウザから Help > SSL Proxying > Install Chales Root Certificate on a Mobile Device or Remote Browser で確認した chls.pro/ssl にアクセスしてCharlesのCertificateをダウンロードして、インストールさせる(信頼してよいものと覚えさせる)。

f:id:niwatako:20180620125040p:plain

f:id:niwatako:20180620125051p:plain

※もしもダウンロード出来ない場合(SDカードがないからダウンロード出来ません、という端末のEmulatorがあった)、Charlesの Help > SSL Proxying > Save Charles Root Certificate... からCertificateをファイルとして保存し(拡張子をcerにしておくのが良いらしい)て、EmulatorにドラッグアンドドロップするとEmulator内のFilesアプリから開けるようになりました。

Credential Useは VPN and apps に設定すれば良い

f:id:niwatako:20180620125120p:plain

Certificate をインストールして利用するには、AndroidバイスにPINまたはパスコードによるロックをかける必要がある様子で、Certificateインストール時に設定を求められる。

f:id:niwatako:20180620125211p:plain

バイス指紋認証はないので Continue without fingerprint で設定する

f:id:niwatako:20180620125240p:plain

今回は適当なPINを設定してみました

f:id:niwatako:20180620125258p:plain

f:id:niwatako:20180620125310p:plain

f:id:niwatako:20180620125318p:plain

ロック中に受信した通知をどうするか。開発時は全部見えてほしいので Show allを選択しました。

f:id:niwatako:20180620125347p:plain

httpsで接続したGoogleとの通信がCharlesから覗けるようになりました。

f:id:niwatako:20180620125546p:plain

困っていること

ダウンロードサイズが大きい時、 ERR_INCOMPLETE_CHUNKED_ENCODING が起きてCharlesとデバイス間でデータの受け渡しが失敗する様子。

Charlesのプロキシサーバーが原因だろうか。以下参考にNginxの場合の記事。

osa.hatenablog.com

記事で紹介されているNginxで言うところの proxy_buffering みたいな設定をさわれる箇所がCharlesの設定には見当たらない。

しかしそもそも、iOSシミュレーターやMacではファイルサイズ関係なくCharles通せるのだけど、どうしてだろう。