SSL Pinning は回避できるのか?
1. SSL Pinning とは何か、どのように動作するのか?
SSL(Secure Socket Layer)Pinning は、開発者がクライアント側で使う技術で、**中間者攻撃(man-in-the-middle)**を防ぐためのものです。
この技術では、開発時に信頼できる証明書のリストをクライアントアプリに埋め込み(ピン留め)、実行時にサーバー証明書と照合します。
SSL ハンドシェイクの後も、クライアントはサーバー証明書を再検証します。サーバー証明書とローカルに保存された証明書が一致しない場合、接続は単に切断され、そのサーバーにユーザーのデータが送信されることもありません。
2. SSL Pinning の有無による違いは?
この仕組みにより、ユーザーのデバイスは信頼できるサーバーとだけ通信するようになります。
そのため、自己署名証明書を生成する中間者型アプリが、アプリの機能やサーバーとの通信方法を解析するのを防ぐために使われることがよくあります。
例として、Proxyman で Product Hunt と Dropbox の通信をキャプチャしてみましょう。
ご覧のとおり、Product Hunt はクライアントで SSL Pinning を使用していません。そのため、Proxyman はサーバーとクライアントの両方として動作し、Product Hunt との間で送受信されるすべてのデータをキャプチャできます。
Product Hunt の通信は Proxyman でキャプチャされています
一方、SSL Pinning が有効な Dropbox では、Dropbox クライアントが Proxyman の CA(認証局)が事前定義された証明書リストに含まれていないことを検出するため、サーバーへのすべてのリクエストが切断されます。
Dropbox の通信は Proxyman でキャプチャされていません
3. SSL Pinning は回避できるのか?
ピンニングで信頼する証明書の範囲を制限すれば攻撃者を防げることは分かりました。では、このプロトコルを回避する方法はあるのでしょうか?答えは「はい」でもあり「いいえ」でもあります (:
-
その会社の開発者でない場合、アプリのクライアントと通信するための有効な証明書を用意できない可能性が高いです。
-
しかし、会社の開発者であり、元の証明書と対応する秘密鍵を持っている場合は、それらの鍵を中間者型アプリに追加することで SSL Pinning を回避できます。
とはいえ、このプロトコルを回避するために鍵の追加に対応している中間者型アプリばかりではありません (:
4. この先について
この短い記事では、開発者がアプリとの間で送受信される通信を検査できないことがある理由について、基本的な理解を解説しました。
安全なテスト方法
まず、同じデバイスで https://google.com などの通常の HTTPS サイトを開いてください。Proxyman でそのレスポンスを読めるのに、アプリで SSL エラーが表示される場合は、ピンニングが原因である可能性が高いです。自分が開発したアプリであれば、ピンニングを無効にするか、テスト用の証明書を信頼するようにしたデバッグビルドを使用してください。Proxyman は、ピンニングを有効にしたままのサードパーティ製アプリを復号できません。また、許可なくアプリの通信を検査しようとしてはいけません。
SSL Pinning の仕組みやアプリへの実装方法について詳しくは、こちらの RWL コースをご覧ください。
また、中間者型アプリとして動作する Proxyman を使って、自分のアプリの SSL Pinning をテストすることもできます (:
Proxyman は高性能な macOS アプリで、iOS デバイス、iOS シミュレータ、Android デバイス上のアプリやドメインから送信される HTTP/HTTPS リクエストを確認できます。
https://proxyman.com からダウンロードできます。

