#navi_header|技術| 勉強中のメモ。(あくまでも個人の意見や見解です) - Certificate and Public Key Pinning - OWASP -- https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning - Certificate and Public Key Pinning | グローバルサインブログ|SSLサーバ証明書ならグローバルサイン (旧日本ジオトラスト株式会社) -- https://jp.globalsign.com/blog/2013/certificate_public_key_pinning.html - SSL Pinning for Increased App Security by Jay Graves of Double Encore -- http://www.doubleencore.com/2013/03/ssl-pinning-for-increased-app-security/ - LumberBlog: Why app developers should care about SSL pinning -- http://blog.lumberlabs.com/2012/04/why-app-developers-should-care-about.html - スマートフォンアプリのSSLとかの解説っぽいもの - Togetter -- http://togetter.com/li/253658 2014-09追記: - 不正なSSL証明書を見破るPublic Key Pinningを試す - ぼちぼち日記 -- http://d.hatena.ne.jp/jovi0608/20140902/1409635279 - Firefox 32、「Public Key Pinning」を導入へ | マイナビニュース -- http://news.mynavi.jp/news/2014/09/02/034/ - Firefox 32 supports Public Key Pinning -- http://monica-at-mozilla.blogspot.jp/2014/08/firefox-32-supports-public-key-pinning.html - draft-ietf-websec-key-pinning-20 - Public Key Pinning Extension for HTTP -- http://tools.ietf.org/html/draft-ietf-websec-key-pinning-20 - Kazuho's Weblog: 自社サーバと交信するスマホアプリにおけるサーバ証明書の発行手法について(SSL Pinningと独自CA再考) -- http://blog.kazuhooku.com/2014/07/ssl-pinningca.html - スマートフォンアプリのSSLとか - Togetterまとめ -- http://togetter.com/li/253510 - 徳丸 浩 on Twitter: "僕がSSL pinningはアプリケーション要件でやってもいいけど、やってなくても脆弱性ではないことにこだわる本当の理由は、「できればpinningはやってほしくない」と思っているからで、その理由はこちらでも述べました http://t.co/vCJVtKeeQ2" -- https://twitter.com/ockeghem/status/488808334288363520 - 目的 -- OSやライブラリによる証明書チェーンの検証に頼らず、アプリケーション側で独自に、接続先のサーバ証明書を検証する。 --- 具体的にサーバ証明書(X509)のどの項目を検証するのかについては上に挙げた資料参照。 - 技法 -- SSL/TLS通信を行うアプリケーションで、サーバ証明書の検証時に、証明書の公開鍵や署名、ホスト名などをアプリ側で持っているリストと一致しているか検証する。 - 誰が行うのか -- アプリケーションの開発者が行う。ChromeなどWebブラウザアプリや、スマホアプリなど、SSL/TLS接続を行うアプリケーション全般の開発者が行う。 - 背景 (より突っ込んだ"目的") -- 1. 認証局自体が攻撃されて、不正に証明書を発行される事例が近年発生している。不正に発行された証明書を使った悪意のあるサーバに対して、中間者攻撃などを使って誘導された場合、単にルート認証局からの証明書チェーンを検証しただけでは、本当に接続先のサーバが正規のサーバであるか検証できたことにならない。このため、サーバ証明書自体をアプリ側でも検証し、アプリ側に埋め込まれている正規のサーバ証明書と同じ内容か検証する。もしアプリ側の証明書情報と一致しなければ、攻撃者により誘導された不正なサーバに接続している可能性があることを判別できる。 --- 例 : ルート認証局のシステムが攻撃され、攻撃者により勝手にGoogle.comの証明書が発行され、攻撃者が用意したサーバに設定されるケース。攻撃によるものとはいえ、証明書自体は正規のルート認証局から発行されたものであるため、検証自体は成功する。その結果、被害者はGoogle.comに接続していると思い込んで、実際は攻撃者により誘導されたサーバに接続し、重要情報をやりとりする。 -- 2. アプリケーションのSSL/TLS通信を悪意のある利用者が盗聴・改ざんすることを防ぐ。 --- BurpなどMITMに対応してSSL/TLSの内容を盗聴・改ざん可能なプロキシツールがある。 --- これらのプロキシツールはアプリから接続された時にプロキシツール自身がSSL/TLSハンドシェイクを行う。この時、プロキシツールはアプリに対して、アプリ自身が生成したサーバ証明書を提示し、サーバとして振る舞う。プロキシツールは内部で生成した独自のルートCA証明書を保持し、共通してそれを認証局としてサーバ証明書を生成する仕組みを有する(場合が多い)。 --- アプリケーションの通信を解析したい利用者は、これらプロキシツールのルートCA証明書をエキスポートした後、自身の環境に信頼できるルート認証局の証明書としてインポートする。 ---- この部分の難易度をPC/iOS/Androidそれぞれで正確に判定できる情報は持ち合わせてないので不明。 --- このため、単に証明書のキーチェーンだけを検証するだけでは、プロキシツールが介在していることを検出出来ない。サーバ証明書までをアプリ独自に検証することにより、もし一致していなければ、プロキシツールが生成した証明書でありプロキシツールが介在している可能性が考えられ、通信エラーとするなどしてSSL/TLS通信内容を盗聴・改ざんされることを防ぐことが可能になる。(100%防ぐことは出来なくとも、難易度を上げることはできる) -- 3. 金銭面などもろもろの事情により、一般の認証局で証明書を発行できず、自己署名証明書を使いたい。証明書の検証を全く行わない事は危険なので、自己署名証明書のサーバ証明書をアプリ側で保持しておき、OS/ライブラリのルート認証局からのチェーン検証は行わず、サーバ証明書の情報だけを検証したい。 -- (他に何かあるか?) - 実装にはいくつかのバリエーションがありそう。 -- Chrome : Google.comの証明書について、予めChrome内にホワイトリストが埋め込まれていて、それらとの一致を検査しているらしい。 -- 単一のサーバとしか通信しないアプリケーションなら、開発者が予めそのサーバの証明書を入手して、それらの情報をアプリに埋め込み、それと一致するかチェックできそう。 -- Webブラウザなど不特定多数のサーバと接続する場合:そのサーバに最初に接続した時のサーバ証明書情報を覚えておいて、2回め以降の接続でそれと異なるようであれば警告あるいはエラーとするなどありそう。SSHクライアントでよく見かける。 --- ただしこの場合、初回接続時に既に攻撃を受けて攻撃者のサーバに誘導されていればナンセンスである。 -- チェーン検証の有無についてもバリエーションが出そう。 --- OS/ライブラリによる、システムの証明書を用いたチェーン検証+独自のサーバ証明書検証を行うパターン --- 独自の証明書ストアを埋め込み、それによるチェーン検証+独自のサーバ証明書検証を行うパターン --- OS/ライブラリによるチェーン検証も、独自の証明書ストアによるチェーン検証も行わず、単にサーバ証明書の検証だけを行うパターン - デメリット -- サーバ証明書が再発行などで変更された場合、アプリ側に埋め込んだ情報も同期させる必要がある。つまり、アプリも同時に変更して配布する必要があり、自動更新処理などを検討する必要が生じる。 - メモ -- Pinningしていないのはアプリケーションの脆弱性か?・・・どうなんだろう・・。 -- 背景の2番目、SSL/TLS通信の盗聴・改ざんを防ぐためというのは個人的にはあんまりオススメしたく無いかな・・・。アプリの利用者自身により通信内容が見られて、改ざんされても、それでもセキュリティが担保されるようにシステムを作っておくほうが順序としては先の気がする。ただそういう要望がある、かもしれない、というのは認識しておきたところ。 -- SSL Pinningさえしておけば、自己署名証明書でも良いか? --- 最低限度、アプリが妥当と認めるサーバとSSL/TLS接続を確立している、という点は担保できる。 --- しかし、その証明書に対する第三者機関による認証、という点を担保できていない状態になる。 --- ユーザの立場では、サーバ証明書を確認した場合に自己署名証明書だと、本当に正当な相手なのか確認できず、不安が残る。極端な話、アプリもサーバもセットで攻撃者が用意したフィッシングアプリ+サーバを想定すれば、自己署名証明書は利用者に対して不安を残すだけとなる。 --- スマホアプリだとサーバ証明書を確認できるユースケースが限られるなどの議論は出てきそうだが、技術スキルのあるユーザがサーバ証明書を確認することは不可能とはいえない状況である。 --- やはり一般的な認証局に発行してもらった証明書を使ってシステムを構築し、ユーザからも、確かに第三者により身元が証明されたものであることを確認できる状態のほうが適切といえそう・・・。 他: - Forward Secrecy at Twitter | Twitter Blogs -- https://blog.twitter.com/2013/forward-secrecy-at-twitter-0 --- SSL/TLSの接続開始時のセキュリティ技術である "Forward Secrecy" をTwitterでも取り入れてみたよ、という記事(多分)。・・・なんだけど、最後のほうでHTTPSをより強化するためになぜかcertificate pinningが推奨されてる。HSTSとかと一緒になってるので、HTTPS関連の最近の改良トピックを一緒くたに推奨として混ぜ込んだだけ? - SSL/TLS & Perfect Forward Secrecy | Vincent Bernat -- http://vincent.bernat.im/en/blog/2011-ssl-perfect-forward-secrecy.html --- "Forward Secrecy" の解説記事。SSL/TLSの鍵交換に使うアルゴリズムとかその辺の話っぽい。 #navi_footer|技術|