WiresharkでSSL通信の中身を覗いてみる
を拝見し、実際に自分の手を動かしてみたのですが、記事内でも触れられているようにDiffie-Hellman(DH) key exchange
(および楕円曲線を用いたECDH)
では、実際に鍵を送り合うわけではなく、鍵を生成するためのパラメータだけがやり取りされるので、サーバの秘密鍵を持っていても復号できません。
今回はDH鍵交換(以下、DHE)でもWiresharkでSSL/TLSを復号すべく試行錯誤したので、まとめます。
事前の設定内容
VirtualBoxで以下のゲストOSやApacheを立ち上げておきます。
$ cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) $ httpd -v Server version: Apache/2.4.6 (CentOS) Server built: Nov 14 2016 18:04:44 $ rpm -aq | grep mod_ssl mod_ssl-2.4.6-45.el7.centos.x86_64 $ openssl version OpenSSL 1.0.1e-fips 11 Feb 2013
ホストOSとゲストOSのIPは、それぞれ以下のようにアサインしました。
ホストOS | ゲストOS |
---|---|
192.168.10.100 | 192.168.10.104 |
オレオレ証明書はCentOS に Apache HTTPD を導入して SSL を有効にする を参考に作成し、証明書と秘密鍵は以下の名前でssl.confに記載しています。
# サーバ証明書 SSLCertificateFile /etc/httpd/conf/server.crt # サーバ秘密鍵 SSLCertificateKeyFile /etc/httpd/conf/server.key
(参考)DHEを無効にする
参考までにサーバ側とクライアント側でDHEを無効にすることでSSL/TLS通信を復号する方法も記載します。 この方法ではサーバの秘密鍵があれば、SSL/TLS通信を復号することができます。サーバの秘密鍵を外へ出したくないということであれば(むしろ出すべきでないと思いますが)、session keyのみをexportすることでも復号できます。 セッションキーをエクスポートし、秘密鍵を共有することなくWireshark でSSL/TLS 通信を複合 に両方のやり方がありますので、興味がある方はぜひ。
サーバ側でDHEを無効にする
WiresharkでSSL通信の中身を覗いてみる にも記載がありますが、ssl.confで以下のように設定すればOKです。
SSLCipherSuite kRSA
設定後はservice httpd restart
でApacheを再起動しておきます。
この状態でhttpsの通信を発生させ、Server Helloに含まれるcipher suiteを見ると
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
となっており、DHEもECDHEも使われていないことがわかります。
※ssl.confの設定を戻すことをお忘れなく
クライアント側でDHEを無効にする(Firefox)
Firefoxを立ち上げ、アドレスバーにabout:config
と打ち込みます。
dhe
で検索し、DHEおよびECDHEを含むcipher suitesを無効化(false)にします。
以下の太字の箇所が変更箇所です(一番上以外)。
この状態でhttpsの通信を発生させ、Server Helloに含まれるcipher suiteを見ると
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
となっており、サーバ側でDHEとECDHEを無効化したときと同じですね。
※Firefoxの設定を戻すことをお忘れなく
本題
さて、DHEを無効化せずにWiresharkで復号化したいですね。
復号化するにはサーバの秘密鍵ではなく、session keyを入手する必要があります。
まずはホストOSでsession keyをexport先を指定してFirefoxを起動します。
ここではpremaster.txt
にexportさせます。
※Firefoxは閉じた状態で実行しないと怒られます。
$ SLKEYLOGFILE=/YOURPATH/TO/premaster.txt "/Applications/Firefox.app/Contents/MacOS/firefox-bin"
上記を実行すると、いつも通りFirefoxが起動するので、httpsの通信を発生させます。
するとpremaster.txt
には以下のようにsession keyが書き込まれているはずです。
$ cat premaster.txt # SSL/TLS secrets log file, generated by NSS CLIENT_RANDOM xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
※実際にはx
が16進数で表示されるはずです。
この時点では以下のように復号化できていないです。
復号するためには、Wiresharkでpremaster.txt
からsession keyを読むように指定してあげます。
指定方法は、WiresharkのPreference
からProtocols
→SSL
→(Pre)-Master-Secret log filename
でpremaster.txt
を指定します。
※特にサーバの秘密鍵などは指定する必要ありません。
OK
を押下すると以下のようにhttpのパケットが復号できます。
このときのServer Helloに含まれるcipher suiteを見ると
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
となっており、ECDHEでも復号化できていることがわかります。