TLS1.3とDC内での復号に関する熱い議論

各ブラウザや、OpenSSL・BoringSSLといった暗号ライブラリ、ミドルウェアのTLS1.3対応が進んでおり、実際に通信できるところまで来ている。

標準化としても大詰めを迎えている。

前回のIETFより話題に上がっている、TLS1.3に関するDC内での復号を目的とした議論について、新しく「TLS 1.3 Option for Negotiation of Visibility in the Datacenter」という拡張仕様が出ている。


これが割りと盛り上がっているので簡単に整理する

TLS1.3

拡張仕様の話に入る前に、簡単にTLS1.3の現状について触れる。

TLS1.3は、0-RTTハンドシェイクのサポートといったパフォーマンスの改善と、多くのセキュリティ改善が入ったTLSの次期バージョンである。

仕様としても長い間議論されており、draft-21まで出ている。ラストコールまで行ったが、色々の問題で2nd WGLCをやるかと行ったところである。


ただ、一つ大きな課題が残っている。初期より、経路上のファイアウォールなどによりブロックされるという疎通性の問題があり、ハンドシェイクにおけるバージョンネゴシエーションSupported Versions拡張を使用するようになっている。

しかし、それでも疎通性の問題が解決できておらず、前回のIETF99では、1~10%の環境で中間装置の問題で疎通が出来ないケースがあることがわかっている(資料)


疎通性の問題を解決するために、Googleが色々試している。その様子はChrome CanaryのTLS1.3の設定項目を見ると複数の実験バージョンが確認できる。具体的な実験内容は、BoringSSLの該当部分のコードを読む必要がありそうだ。

f:id:ASnoKaze:20171005003240j:plain

おそらく来月開催されるIETF100で、そこら辺の改善についての議論が進むものと思われる。

DC内復号の提案

さて、TLS1.3の標準化が大詰めを迎えるなか、IETFTLS WGでは、TLS1.3のDC内での復号というテーマが出ている。これは、DC内の通信でもTLSを使いながらも、秘密鍵を有していれば任意の通信を復号出来るようにするという要件が特定のエンタープライズ環境であるようで、それを可能にしたいという提案である。

TLS1.3と復号

TLS1.3ではephemeralな鍵交換のみがサポートされており、各セッションごとに暗号化に使用する一時鍵が異なっており、サーバに設定する秘密鍵を有していても復号できなくなっている。


復号しようとするならば、各セッションごとのその一時鍵(セッションシークレット)が必要になる。
最新のopensslであれば -keylogfile を指定することでそれらのパラメータをファイルに残すことも出来る(SSLKEYLOGFILE環境変数を設定することで、各ブラウザでも同様のログを出力可能)

$ openssl s_client -state -connect localhost:443 -keylogfile sslkeylog.log -tls1_3 
//略

$ cat ./sslkeylog.log
# SSL/TLS secrets log file, generated by OpenSSL
SERVER_HANDSHAKE_TRAFFIC_SECRET ce146098355b00754c6fd062f7e0dfdd982bf1b84a51deda78ffe217560852a5 c16440d97afd98db5f2b46c806f342e59e89e5c51c25f89c7614328bd32ab97556ff30c3545dda519fddca59acf95fbf
SERVER_TRAFFIC_SECRET_0 ce146098355b00754c6fd062f7e0dfdd982bf1b84a51deda78ffe217560852a5 0b2b1a6e4648883b0505c17ea6580f4d378a54d468d8b0a5dd07c4867725e1615191d7226d2e87e6f89866daa74ffb91
CLIENT_HANDSHAKE_TRAFFIC_SECRET ce146098355b00754c6fd062f7e0dfdd982bf1b84a51deda78ffe217560852a5 3fd9a41f47028ad33610ee7cbae09120c11b8e64d478ba73745c85078cbdbaa01673ef4589cdf4589c9b2fa22d8ac150
CLIENT_TRAFFIC_SECRET_0 ce146098355b00754c6fd062f7e0dfdd982bf1b84a51deda78ffe217560852a5 f8371e8d335b6e79c7e58be7ee26a6254b848311b320ddb37bc7a8b911ff34f22a812be2dd0e5aaae45208439100eba0

このkeylogfileファイルをWiresharkに設定すれば復号することも出来ます。

ただし、この場合は各サーバが各セッション毎に鍵情報を保管することになり、特定の鍵で任意の通信を復号することは出来ない。

IETF99 (7月)

そのような中で、エンタープライズ環境での影響についてIETF99で発表されたのが下記の資料である。
Impact of TLS 1.3 on Enterprise Network Operations


この発表では合わせて、「Data Center use of Static Diffie-Hellman in TLS 1.3」という、サーバからのkey_shareに静的な鍵を使うようにする提案も行われている。これによって、その鍵を持っていればすべてのセッションを複合できるようになります。

この発表は大変大きな議論を呼び、さらに米国政府関係者が提案を支持したことにもよって、会場のマイクの前には長蛇の列が出来るような状況になりました。もちろん、そのような機能でTLSを弱くすることは出来ないという主張である。


twitter上でも #tlsfight99 ハッシュタグで熱い意見が流れています。
twitter.com

最終的に会場内でこの議論に関する温度感が確認(hum)されましたが、この議論を続けるべきと反対派はだいたい半々でした。

新しい提案

以上の流れが会った上で、DC内で復号出来るようにする拡張仕様が、別の人によって提案がされています
https://tools.ietf.org/html/draft-rhrd-tls-tls13-visibility-00

TLS Visibility Extensionという拡張を定義されており、クライアントとサーバによってハンドシェイク時に合意され、使用されます。

SSWrapDH1とSSWrapDH2という2つの鍵を使用します。

  • SSWrapDH1: 通信を復号するのに使用する秘密鍵とその公開鍵
  • SSWrapDH2: 各セッションごとに使用される秘密鍵とその公開鍵


TLS1.3通信を行う際は

  • SSWrapDH1公開鍵とSSWrapDH2秘密鍵から鍵Keを生成する
  • Keを使用して、TLS 1.3セッションEarly SecretとHandshake Secret(セッションシークレット)を暗号化します。
  • Server HelloメッセージのTLS Visibility Extensionに、SSWrapDH1公開鍵(フィンガープリント)、SSWrapDH2公開鍵、および暗号化されたセッションシークレットの識別子を送信します。


復号する際は

  • TLS Visibility ExtensionからSSWrapDH1公開鍵を取得する
  • SSHWrapDH1秘密鍵とSSWrapDH2公開鍵を使用してKeを生成する
  • Keを使用して、TLS Visibility Extensionで運ばれたセッションシークレットを解読する
  • セッションシークレットを使用して、TLS 1.3セッションの復号化に必要なキーイングマテリアルを導出する


このようにして秘密鍵所持者によって任意の通信を複合出来るようになっている。
他の方法の検討や、Security Considarationsは仕様の中で記述されている。

引き続き来月開催されるIETF100で議論があるかもしれない。
さてさてどうなるのだろうか。