RFC 8446: TLS 1.3
TLS 1.3はハンドシェイクを1往復に短縮し、RSA鍵交換やCBCなどの危険なレガシーを規格から一掃する。(EC)DHEによる前方秘匿性とAEADを必須化し、証明書までを暗号化して、速さと安全を同時に底上げした。
- TLS 1.3(RFC 8446、2018年)はClientHelloへkey_shareを載せ、鍵合意・認証・暗号化開始を1-RTTへ短縮した。再接続では0-RTT送信も可能だが、再送攻撃への対策が要る。
- 鍵交換は(EC)DHEの一時鍵に限定して前方秘匿性を必須化し、暗号はAEADのみへ絞った。RSA鍵交換・静的DH・CBC・RC4・TLS圧縮といった攻撃の温床を規格から削除し、鍵導出はHKDFへ一本化している。
- ServerHello以降の証明書とFinishedは暗号化する。版交渉はsupported_versionsで行い、格下げはServerHello.randomの番兵値で検知する。0-RTTデータだけはリプレイ可能性が残る。
このRFCが決めたこと
横にスクロール
RFC 8446(2018年8月)は、TLS 1.2を定めたRFC 5246を置き換える新しいセキュリティプロトコルの規格です。1.2までの小刻みな改良とは違い、TLS 1.3はハンドシェイクを一から設計し直しました。狙いは二つ、速さと安全の両立です。往復回数を1-RTTに削り、同時に長年攻撃の温床だったレガシー機能を規格そのものから取り除きました。TLSはTCPの上で動くため、土台のTCP/UDPを押さえておくと理解が深まります。
決めた柱は、(EC)DHEによる前方秘匿性の必須化、AEAD暗号のみへの限定、ハンドシェイク後半の暗号化、そしてダウングレード保護です。電文レベルの詳細はTLS 1.3ハンドシェイクの内部で追えます。
要点の精読
1-RTTハンドシェイク
TLS 1.2は鍵合意に2往復かかりました。1.3では、クライアントが最初のClientHelloに鍵共有(key_share)を相乗りさせ、使う楕円曲線群を先読みで提示します。サーバーは1往復目のServerHelloで自分のkey_shareを返し、その直後から証明書やFinishedを暗号化して送れます。結果、アプリデータは1往復で流れ始めます。
Client Server
ClientHello
+ supported_versions (TLS 1.3)
+ key_share -------->
ServerHello
+ key_share
{EncryptedExtensions}
{Certificate}
{CertificateVerify}
{Finished}
<-------- [Application Data]
{Finished} -------->
[Application Data] <-------> [Application Data]
{ } = ハンドシェイク鍵で暗号化 [ ] = アプリ鍵で暗号化
なお交渉するTLSバージョンは、旧来のバージョン欄(互換のため0x0303=TLS 1.2に固定)ではなく、supported_versions拡張で示します。
0-RTT(アーリーデータ)
一度接続した相手には、前回発行の事前共有鍵(PSK)を使い、ClientHelloと一緒にアプリデータ(アーリーデータ)を送れます。往復ゼロで最初のリクエストが届き、体感速度はさらに上がります。ただしこの初回データだけは(EC)DHEを経ないため、後述のリプレイ耐性を持ちません。
鍵スケジュール(HKDF)
1.3の鍵導出はHKDFへ一本化されました。HKDF-Extractで秘密をまとめ、Derive-SecretとHKDF-Expand-Labelで用途ごとに枝分かれさせます。Early Secret から Handshake Secret、Master Secret へと段階的に鍵を育て、ハンドシェイク用とアプリ用のトラフィック鍵を別々に取り出します。導出の入力にメッセージのハッシュを織り込むため、鍵はやり取りの文脈に強く結び付きます。
廃止された危険機能
「安全な選択肢を残す」のではなく「危険な選択肢を消す」のが1.3の設計思想です。
| 項目 | TLS 1.2 | TLS 1.3 |
|---|---|---|
| 鍵交換 | RSA鍵交換・静的DHも可 | (EC)DHE一時鍵のみ(前方秘匿性が必須) |
| 暗号方式 | CBC・RC4・AEADが混在 | AEADのみ |
| TLS圧縮 | あり(CRIMEの温床) | 削除 |
| ハンドシェイク往復 | 2-RTT | 1-RTT(再訪は0-RTT) |
| 証明書の可視性 | 平文で流れる | 暗号化して隠す |
RSA鍵交換を消したのが最大の転換です。サーバーの秘密鍵が将来漏れても過去の通信を遡って復号できない、これが前方秘匿性で、一時鍵の(EC)DHEだけを許すことで保証します。再交渉やカスタムDH群、MD5/SHA-1署名も姿を消し、選べる暗号スイートはAEADと結び付いた数種類だけに絞られました。
つまずきやすい点
最大の落とし穴は0-RTTのリプレイです。アーリーデータは新鮮さを保証できず、攻撃者が丸ごと記録して後から再送できます。サーバー側の重複排除にも限界があるため、0-RTTに載せてよいのは副作用のない冪等な要求(値の変わらないGETなど)に限るのが鉄則です。決済や在庫更新のような操作を0-RTTで受けてはいけません。
アーリーデータはリプレイされうる前提で設計します。副作用のある操作は通常の1-RTT確立後に回し、アプリ側でも重複検知(使い捨てチケットや新鮮さの窓)を用意しておくのが安全です。
もう一つがダウングレード保護です。1.3対応サーバーが1.2以下で応答するとき、ServerHello.randomの末尾8バイトに番兵値(先頭7バイトがDOWNGRD、最終バイトが0x01など)を埋め込みます。1.3対応クライアントはこれを検知し、中間者による格下げ攻撃であれば接続を中断します。この値はサーバー認証で保護されるため、攻撃者が黙って書き換えることはできません。
まとめ
TLS 1.3は、往復を削って速くし、危険な選択肢を規格から消して安全にした、TLSの大掃除です。(EC)DHEの前方秘匿性とAEAD、暗号化されたハンドシェイクが標準になり、設定ミスの余地そのものが減りました。唯一0-RTTだけはリプレイという新しい注意点を持ち込むので、冪等性を意識して使い分けます。関連規格はRFC精読の各記事で広げてください。
RFC精読の記事ガイド
RFC 8446: TLS 1.3を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
RFC
比較で見る軸
難易度: advanced / カテゴリ: RFC精読 / タグ数: 5
導入後に効く点
鍵交換は(EC)DHEの一時鍵に限定して前方秘匿性を必須化し、暗号はAEADのみへ絞った。RSA鍵交換・静的DH・CBC・RC4・TLS圧縮といった攻撃の温床を規格から削除し、鍵導出はHKDFへ一本化している。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- RFC精読
- タグ数
- 5
判断チェックリスト
- 自社の用途が「RFC / TLS」に近いか確認する。
- 強みである「TLS 1.3(RFC 8446、2018年)はClientHelloへkey_shareを載せ、鍵合意・認証・暗号化開始を1-RTTへ短縮した。再接続では0-RTT送信も可能だが、再送攻撃への対策が要る。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。