TLSハンドシェイクの仕組みと実務上の注意点 — TLS1.2 と TLS1.3 を深掘り解説
はじめに
TLS(Transport Layer Security)は、インターネット上でデータの機密性、完全性、認証を確保するための主要プロトコルです。TLSの中核にある「ハンドシェイク」は、クライアントとサーバーが安全に通信を開始するための一連のメッセージ交換を指します。本稿ではTLSハンドシェイクの目的、TLS1.2とTLS1.3のフロー比較、鍵導出の仕組み、主要な拡張、セキュリティ上の注意点、運用ベストプラクティスまでを技術的に深掘りします。
TLSハンドシェイクの目的
相互認証(通常はサーバー証明書によるサーバー認証、必要に応じてクライアント認証)
暗号スイートのネゴシエーション(鍵交換アルゴリズム、暗号アルゴリズム、ハッシュ/認証方式)
共通のセッション鍵の安全な確立(機密性と完全性を担保する対称鍵)
将来の盗聴から守るためのフォワードシークレシー(ephemeral鍵の使用)
TLS1.2 のハンドシェイク(典型的なフロー)
TLS1.2のハンドシェイクは従来型で、主に以下のメッセージ列で構成されます(簡略化):
ClientHello:クライアントがサポートするプロトコルバージョン、ランダム、サポートする暗号スイート、拡張を送信
ServerHello:サーバーが選択したプロトコルバージョン、ランダム、暗号スイートを返答
Server Certificate:サーバー証明書チェーン(通常はX.509)を送信
ServerKeyExchange(必要な場合):RSA以外の鍵交換(DHE/ECDHEなど)や追加パラメータを送信
CertificateRequest(必要な場合):クライアント認証を求める
ServerHelloDone:サーバー側のハンドシェイク段階終了
Client Certificate(要求があれば):クライアント証明書を送信
ClientKeyExchange:プリマスターシークレット(RSA方式)またはクライアントのDHパブリック値(DHE/ECDHE)を送信
CertificateVerify(クライアント証明書使用時):クライアントが秘密鍵保持者であることを証明する署名
ChangeCipherSpec:以降のメッセージは協議済みの暗号で保護されることを通知
Finished:ハンドシェイクの整合性を検証するためのハッシュ値を交換
鍵導出は、ClientKeyExchangeで得たプリマスターシークレットからPRF(擬似ランダム関数)を用いてマスターシークレットを生成し、そこからセッション鍵(MAC鍵、暗号鍵、IV等)を派生させます。
TLS1.3 のハンドシェイク(主な違いと利点)
TLS1.3(RFC8446)は設計が簡素化され、早期暗号化、脆弱な機能の廃止、性能改善に重点が置かれています。主な違いをまとめます。
フルハンドシェイクでもラウンドトリップ数が削減:クライアントはClientHelloを送り、サーバーがServerHelloとEncryptedExtensions、Certificate、CertificateVerify、Finishedを返す流れが多く、暗号化されたトラフィックの開始が早い。
0-RTT再接続:以前のセッション情報を使えばクライアントは最初の往復でアプリデータを送信可能(ただしリプレイ攻撃の可能性あり)
非推奨機能の削除:RSA鍵交換、静的RSA暗号化、CBCベースの暗号、MD5やSHA-1の弱いPRF等が除去
鍵導出の単純化とHKDFの使用:HKDF(HMACベースの鍵導出)が中心となり、ハンドシェイクトランスクリプト(handshake transcript)の整合性が重要
AEAD(例:AES-GCM、ChaCha20-Poly1305)の標準化:暗号化と完全性検証を一体化
鍵交換方式とフォワードシークレシー
鍵交換方式はセキュリティと性能に直接影響します。主な方式:
RSA(鍵暗号化):古い方式でプリマスターシークレットをRSAで暗号化して送る。TLS1.3では廃止。フォワードシークレシーを提供しない。
DHE/ECDHE(ディフィー・ヘルマン、楕円曲線版):エフェメラルな鍵を用いることでフォワードシークレシーを実現。現在の推奨はECDHE。
PSK(事前共有鍵):高速な再接続に有利。単独だと初期認証に課題があるため、PSK+(DHE/ECDHE)との併用が推奨される。
鍵導出とハンドシェイクトランスクリプト
TLSではハンドシェイク中のメッセージシーケンス全体から鍵を導出し、メッセージの整合性を検証します。TLS1.2ではPRF(通常はHMACベース)、TLS1.3ではHKDFが使われます。特にTLS1.3では過去のトランスクリプトに基づく鍵更新(HKDF-Expand/Extract)が厳密に定義されており、Finishedメッセージはハンドシェイク全体の正当性の最終チェックを行います。
証明書と認証
サーバー証明書はX.509形式が一般的で、クライアントは証明書のチェーンを検証し、信頼できるルートCAに到達することを確認します。検証ポイント:
署名アルゴリズムと鍵の強度(RSA鍵長、ECDSA曲線等)
有効期間(notBefore/ notAfter)
失効情報(OCSP、CRL、またはOCSP Stapling)
ホスト名検証(CN/subjectAltName)
証明書ピンニングやCT(Certificate Transparency)ログの確認(運用レベルの追加対策)
拡張と運用上重要な機能
SNI(Server Name Indication):ホスト名をClientHelloに含め、1つのIPで複数ドメインの証明書を扱う。
ALPN(Application-Layer Protocol Negotiation):HTTP/2やHTTP/1.1のネゴシエーションをハンドシェイクで行う。
supported_versions:TLS1.3などのバージョンネゴシエーション。
Renegotiation info(RFC5746):脆弱性対策済みの安全な再ネゴシエーション実装。
セッション再開と0-RTT
セッション再開は通信のオーバーヘッドを削減します。TLS1.2ではセッションIDやSession Ticketを使い、TLS1.3ではより安全に設計されたPSKベースの再開機構と0-RTTを導入しました。0-RTTは高速化に有効ですが、リプレイ攻撃のリスクがあるため再送不可な操作(状態変更)には注意が必要です。実装ではアプリケーションレベルでの対策(リプレイ検出、トークン併用など)が求められます。
暗号選定とAEAD
現在の実務ではAEAD(Authenticated Encryption with Associated Data)が標準です。代表的なもの:
AES-GCM:ハードウェア支援がある環境で高速
ChaCha20-Poly1305:モバイルや低リソース環境で有利
古いMAC+CBC方式は多くの脆弱性(BEAST、POODLE、Lucky13等)を生んだため避けるべきです。
攻撃ベクトルと対策
中間者(MITM):正規の証明書でない限り接続は警告されるが、CAの誤発行やユーザーの無効な許可で突破されるリスクがある。HSTSや証明書ピンニングでリスク低減。
ダウングレード攻撃:プロトコルや暗号を強制的に低いものにさせる攻撃。TLS1.3や拡張による保護、そしてサーバーの安全な設定で防止。
リプレイ(0-RTT):アプリケーション側で再発防止を実装。
証明書失効の不備:OCSP Staplingや短い有効期間、定期的なローテーションが有効。
運用上のベストプラクティス
TLS1.3を有効にし、サポートできないクライアント用には安全にフォールバックを行う。ただし古いTLS1.0/1.1は無効化。
強力な暗号スイート(ECDHE + AEAD)を選択し、弱い鍵や古いアルゴリズムを無効化。
証明書管理を自動化(例:Let’s Encrypt、ACME)し有効期間を短くする。
OCSP StaplingやTLS証明書の監視(Certificate Transparencyログの確認)を導入。
Perfect Forward Secrecy(PFS)を提供する鍵交換を必須化。
ログやメトリクスを有効化してTLSネゴシエーション失敗や脆弱なクライアントを検出。
将来への展望:ポスト量子暗号など
量子コンピュータの進展に備え、IETFや業界はポスト量子暗号(PQC)をTLSに組み込む研究を進めています。将来的にはハイブリッド鍵交換(古典+量子耐性アルゴリズム)による移行が現実的です。運用側では、長期保存が必要なデータの保護(harvest-now, decrypt-later)対策として早めの準備が求められます。
まとめ
TLSハンドシェイクは単なる鍵交換の手続きではなく、通信の認証、暗号化方式のネゴシエーション、将来の盗聴から守るための重要なプロセスです。TLS1.3はパフォーマンスとセキュリティの両面で多くの改善をもたらしましたが、運用上は正しい設定、証明書管理、再開・0-RTTのリスク管理が不可欠です。設計・実装・監視の各層でベストプラクティスを守ることが安全なTLS運用につながります。
参考文献
RFC 5246 - The Transport Layer Security (TLS) Protocol Version 1.2
RFC 8446 - The Transport Layer Security (TLS) Protocol Version 1.3


