[レポート] TLS 1.3 の標準化動向 #tls13_study ※補足説明付き
現在仕様策定中の TLS1.3 ですが、その標準化動向と、最新のドラフトを元にハンズオンを行う勉強会 TLS1.3 Study が先日(2/14)開催されました。
そこで行われた IIJ 山本和彦氏のプレゼンテーションについてレポートします。実際に TLS1.3 の実装を手がけられ draft 策定作業にも参加されている氏の解説は非常に実践的なものでしたが、正直なところわたし自身理解が追いついていないので、以下ではところどころ説明を補っています。わたしが補った部分は 斜体 になっているので、その旨ご了承下さい。
なお、今回の会場は東京日本橋のサイボウズ社さまのオフィスでした。
※以下敬称略
レポート : TLS 1.3 の標準化動向
ドラフト 18 から最新のドラフトまでの変更を振り返ります
- 登壇者 : 山本和彦
資料
TLS 1.2 についての説明はここでは割愛
- 下記の文献を参照
- TLS 1.3 は、1.2 が抱える下記の問題を解決する
- プロトコル自体の欠陥
- 圧縮、再ネゴシエーション
- 暗号技術の老朽化
- RC4、CBC、SHA-1
- 継ぎ接ぎだらけの仕様
- 拡張の RFC が多過ぎる
- プロトコル自体の欠陥
- TLS 1.3 が求められるようになった背景については、下記資料も分かりやすいと思いましたのでご紹介します
- HTTP/2, QUICからTLS1.3へ ※リンク先PDF
TLS 1.3 の特長
- 安全性の向上
- 老朽化した暗号の排除
- 広域監視の存在
- = トラフィックはすべて保存されていると考えるべき
- = 鍵交換は前方秘匿性を持つべき
- = Diffie Hellman 鍵共有の復権(DHE, ECDHE)
- 再ネゴシエーションはとても危険だと分かった
- 中間者攻撃、サーバへのDoS攻撃
- 不自由で安全でない設計(認証情報を平文で流す必要性)
- 圧縮も危険
- 圧縮率の差から情報(クッキーなど)を盗む攻撃 - CRIME攻撃
- 前方秘匿性 > 鍵は動的に生成、静的な鍵は使わない
- つまり TLS1.2 はこれらの問題を抱えている ということ
- 老朽化した暗号の排除
- 機密性の向上
- プロトコル上、クライアント証明書はかならず暗号化される
- ハンドシェイクの一部も暗号化する
- 速度の向上
- 1-RTT 前方秘匿性あり
- 1-RTT = クライアントからのリクエストに対する 1回目のサーバからの応答
- 0-RTT 前方秘匿性なし
- 秘匿性がないのは 0-RTT のときに送信されたデータのみ
- 1-RTT 前方秘匿性あり
補足: 前方秘匿性
- forward secrecy あるいは perfect forward secrecy
- 概念自体は古い(1989年にはあった)
- 通常の暗号の場合、長期にわたって同じ鍵が使われる
- 将来的にその鍵が漏洩した際、過去に遡って「記録された暗号通信」が解読されてしまう
- そのセッションでしか利用しない一時的な鍵ペアを都度生成して使用すれば、解読される範囲を限定的にできる
- つまり、通信が行われた時点から将来(前方)にわたって秘匿性が確保できること = 前方秘匿性
- 参考 : Internet Infrastructure Review(IIR)Vol.22 | セキュリティレポート・技術レポート|IIJ
- 1.4.2 Forward Secrecy
TLSのハンドシェイク比較
- フルハンドシェイクは両方にある(当然)
- 再開(resumption)と PSK は統合された
- PSK = Pre-Shared Key
- 動作がよく似ていたので共通化された
- 再ネゴシエーションは廃止
- 再トライと 0-RTT が増えた
暗号スイート
※プレゼン資料より
- TLS 1.2 の暗号スイートは非常に複雑
- 書式や表記に統一性がなかった
- 「SHAと書いてSHA256と読む」= SHAと書いてあっても実体は SHA256 である場合がある
- TLS 1.3 では鍵交換とサーバ認証が削除された
- AEAD 暗号と同時に認証もする
- AEAD = 認証付き暗号 - Authenticated Encryption with Associated Data
- 暗号化と認証を同時に行わないと脆弱
フルハンドシェイク
- 前方秘匿性のある 1-RTT
- 資料中の薄いグレー = 暗号化されている
- クライアントから先に公開鍵をつける
- 「サーバ証明書を送信してきたからと言って認証できたわけではない」
- 一緒に署名も一緒に貰う = 検証可能になる
- 何を署名するかはプロトコルで決まっている
- 秘密鍵を使わせることが大切
- これまでは鍵交換とサーバ認証が同時だったので暗黙のうちに秘密鍵が使われていた
- Finished = ハンドシェイク内のデータのハッシュ
- ハンドシェイクを暗号化する鍵とコンテンツを暗号化する鍵は違う
- Finished のあとすぐ暗号が変わる
- CCS (ChangeCipherSpec) は別に必要では無かった
- 暗号の変わるタイミングが分かってるため
ハンドシェイク部分の暗号化
- ALPNの例
- サーバからの返答 ServerHello も暗号化される
- 実際の通信が HTTP1.1 なのか HTTP/2 なのかすら秘匿される
再トライ
- 鍵交換の拡張
- HRR : クライアントが指定した暗号方式(公開鍵)をサーバが受け取れない場合、サーバがクライアントに再トライを促す
- HRR = HelloRetryRequest
- 頭のいいクライアント(ブラウザ)はそれを覚えておく
- 次回アクセス時には、最初から有効な鍵交換方式でアクセスを開始する
セッションの再開 (TLS1.2)
- 再開 = Resumption
- セッション ID
- 「ID」としてセッション再開のための情報をうめこむ = セッションチケット
- セッションチケットの場合、再開のための情報をサーバは持たない
- セッション ID / チケットを使って前のセッションの通信相手を認証
- 公開鍵暗号は使わない
PSK (TLS1.2)
- PSK = 事前設定した鍵(Pre-Shared Key)
- PSK 持ってるなら証明書や署名を省略できる
- 公開鍵暗号は使わない
再開と PSK はフローが似ている
- 統合しよう
- 外部 PSK : TLS1.2 でいうところの PSK
- 再開 PSK : TLS1.2 での再開(resumption)
- 前方秘匿性のある 1-RTT 再開
0-RTT
- early data オプション
- PSK あるなら最初から暗号化できるのではないか?
- ※ 資料修正:サーバ側も
+ early data
が付く - 鍵は 3 段階
- early data 用
- ハンドシェイク用
- データ用
early data
というクライアントデータはいくつでも送信できる- EndOfEarlyData フィールドが必要
- 前方秘匿性なし、リプレイ攻撃可能なのでよく考えて使用すること
- リプレイ攻撃 = キャプチャしたパケットを再送信して攻撃に活用する手法
標準化の歴史
- draft 18 以降
- ラストコールx3
- draft 19, 21, 23
- LCのあいだに新しい仕様がはいってくるのは珍しい
ある draft で決まった仕様も、その後の draft で変更されているものがあります
draft 18
- ECDHE X25519, X448
- DJB によってリリース
- 米国政府機関以外のところで開発された = TLS1.3 開発者に大人気
- NIST P256
- 開発者にはあまり人気が無い(NIST = アメリカ国立標準技術研究所)
- RSA 署名で RSASSA-PSS を使う
- RSASSA-PKCS1-v1_5 の代わり
- 現在はこちらが主流
- パディング等が違うだけで情報の中身は同じ
- RSASSA-PKCS1-v1_5 の代わり
- 3 段階の鍵スケジューリング
- ealry traffic secret
- handshake traffic secret
- application traffic secret
- 鍵の切り替わりを示す ChangeCipherSpec は不要なので削除した
- TLS1.2 と互換性のない ServerHello の規格
- ClientHello は互換性あり
- SessionID、CompressionMethod がない
- パーサの中で条件分岐せざるを得ない
draft 19
- 大きな変化
- 0-RTT が追加
early_data
とticket_early_data_info
拡張が統合end_of_early_data
がアラートからハンドシェークメッセージへ変更- -> 仕様漏れがありその後の draft で修正
draft 20
- 鍵スケジューリングで使う文字列を短くした
draft 21
- TLS1.3 0-RTT に対してセキュリティ上の問題がある旨指摘が入った
- NewSessionTicket に nonce いれるようにした
- ticket が同じでも異なる PSK 鍵が生成されるように
- 0-RTT 攻撃に対するドキュメントの整備
- 緩和する方法
- single-use チケット = サーバが複数台あると実装が無理
- Client Hello Recording = Firefox (NSS) にて実装
draft 22
- TLS1.2 ではない、として通信を遮断する middle box があった
- プロキシや UTM, ファイアウォールなど?
- facebook の技術者が報告
- 対策として、TLS1.2 との非互換部分を修正、そろえる形に
- ServerHelloを1.2に
- バージョン番号も 1.2(0x0303)決め打ち
- 真のバージョン番号は
supported_version
で指定する - HelloRetryRequest 廃止
- Random フィールドに特別な値を埋め込んで HRR とする
- レコードのバージョンは TLS1.2 決め打ち
- (doraft 18 時点では削除されていた) ChangeCipherSpec (CCS) が復活
- でも情報として不要なので無視するように、と仕様に書かれている
draft 23
key_share
拡張の値を変更- とあるメーカーのプリンタが無届けで 40番を使用していた
- そのため重複した
- middle box へのリクエストが仕様に明記された
Q&A
- SNI をみている UTM が動かなくなる可能性はあるか?
- ClientHello は平文なので、そこを見ているのであれば問題ない
- 次の London WG で策定されそうか?
- 大きな issue は (今のところ) ない
- みんないけると思っているので、draft 22,23 準拠の実装が増えた
TLS 1.3 draft 23 ハンズオン
プレゼンテーションのあと、実際に TLS 1.3 をつかっての通信を行うハンズオンが行われました。
内容のご紹介と、後日再現試験を行った際のキャプチャをご紹介します。
- ブラウザを利用しての TLS 1.3 アクセス
- Firefox Nightly
- stable とプロファイル情報が共通化される可能性があるようなので注意して下さい。今回自分では使用しませんでした
- Chrome Canary
- https://www.chromium.org/getting-involved/dev-channel
- macOSの場合でも Canary 版は stable と共存(別プロファイルで動作)できます
chrome://flags#tls13-variant
にアクセスし設定を「Draft 23」に変更- DevTools で確認しながらアクセスする
- https://www.chromium.org/getting-involved/dev-channel
- TLS 1.3 が有効化されている Web サーバ
- Firefox Nightly
Chrome Canary の設定画面は下記のようになっていました(画像は変更済みの状態)。
以下は、実際に Chrome Canary でアクセスした際のキャプチャです。
tls-simpleclient
を使用しての各種ハンドシェイクの確認- Wireshark の開発版を使えば確認可能
実際に https://www.tls13.facebook.com/ へアクセスした際のパケットをキャプチャした様子はこちらになります。
所感
TLS 1.3 は 1.2 から比べると、単なる暗号技術の最新化にとどまらない、ネットワーク環境の変化が盛り込まれているように思えました。それは「全ての通信パケットが傍受・記録されている」という前提からくる「前方秘匿性(将来にわたって解読されることのない暗号)」への要求や機密性の向上、高速かつ安全な通信のための 0-RTT などからうかがえます。
その一方で既にある通信機器(ミドルボックス)への互換性確保のために、本来は必要ではないフィールドを残したり、あえてTLS 1.2のバージョン番号を継続して使うなど、実用性・運用性が重視されています。
このまま問題が無ければそう遠くないうちに策定が完了するとのことなので、それから各種の実装が出回ることになるかと思います。AWS というくくりでみれば、HTTP/2 の時のように ALB や CloudFront が終端したり、各種エンドポイントが対応したり。。。という動きになるのでしょうか。継続して見ていきたいと思います。
末筆になりますが、有益な情報を惜しみなく提供して下さった山本さまと主催者の方々に感謝いたします。