🔐
TLSハンドシェイクとはTLSハンドシェイクは、暗号化通信を始める前の「合意形成プロセス」です。 日常のたとえでいうと、初対面の相手と秘密の話をする前に「どんな暗号で会話するか」「本当にその人か」を確認するステップです。
ブラウザで https:// のURLにアクセスすると、HTTPリクエストを送る前に必ずこのTLSハンドシェイクが行われます。 ハンドシェイクが完了して初めて、パスワードやクレジットカード番号などの機密データを安全に送受信できるようになります。
TLS 1.3ではわずか1往復(1-RTT)でハンドシェイクが完了するため、 HTTPS接続のオーバーヘッドは非常に小さくなっています。上のツールでステップを進めて、各フェーズで何が行われるか確認してみてください。
⚡
TLSの特徴- 🔒暗号化(Encryption):通信内容をAESなどの暗号アルゴリズムで暗号化します。Wi-Fiを傍受されても、暗号鍵がなければデータは読めません。上のツールで暗号スイートの欄に表示される「AES-128-GCM」がこの暗号化方式です。
- 📜認証(Authentication):サーバー証明書を使って「通信相手が本物か」を確認します。認証局(CA)が発行した証明書により、偽サイトへの接続を防ぎます。ブラウザのアドレスバーに表示される🔒マークがこの認証の証です。
- ✅完全性(Integrity):メッセージ認証コード(MAC)により、データが途中で改ざんされていないことを保証します。1ビットでも変わると検出されます。
- 🛡️前方秘匿性(Forward Secrecy):TLS 1.3ではECDHE鍵交換を必須としており、仮にサーバーの秘密鍵が将来漏洩しても、過去の通信内容は解読できません。セッションごとに一時的な鍵ペアを生成するためです。
🌍
ユースケース🌐 HTTPS Webブラウジング
Chrome・Safari・FirefoxなどすべてのブラウザがTLSを使用。Google検索やYouTubeもHTTPS必須
🔗 REST API / GraphQL
Stripe・GitHub・AWSなどのAPI通信。OAuth認証トークンやクレジットカード情報の保護
📧 メール(SMTPS / IMAPS)
Gmail・Outlookなどのメール送受信。STARTTLS拡張でSMTP通信を暗号化
🏢 マイクロサービス間通信
Kubernetes内のサービスメッシュ(Istio等)でmTLSを使ったサービス間の相互認証
📖
用語解説Client Hello
= クライアントからの最初のメッセージ
TLSハンドシェイクの最初に送るメッセージです。「自分はこれらの暗号方式に対応しています」という提案リストを送ります。 対応するTLSバージョン、暗号スイートの候補、鍵交換用のパラメータ(Key Share)、ランダム値が含まれます。 上のツールでステップ1に進むと、青いパケットとして表示されます。
Server Hello
= サーバーからの応答メッセージ
サーバーがClient Helloの候補リストから1つの暗号スイートを選び、自身の鍵交換パラメータとともに返します。 TLS 1.3では同時にサーバー証明書とFinishedメッセージも送るため、1往復でハンドシェイクが完了します。 上のツールでステップ2に進むと、緑のパケットとして表示されます。
暗号スイート(Cipher Suite)
= 暗号化方式の組み合わせセット
暗号スイートとは、1回の通信で使うアルゴリズムの組み合わせです。 例えば TLS_AES_128_GCM_SHA256 は 「AESで暗号化、GCMモードで完全性チェック、SHA-256でハッシュ」という意味です。 上のツールの「暗号スイート」欄に表示される値がこれです。
証明書(Certificate)
= サーバーの身分証明書
証明書はサーバーが「自分は本物の example.com です」と証明するためのデジタル文書です。 信頼できる第三者(認証局 / CA)が署名しており、ブラウザは証明書チェーンをたどって信頼性を検証します。 上のツールのステップ3で証明書検証のプロセスが表示されます。
鍵交換(Key Exchange)
= 安全に共通の秘密を作る仕組み
鍵交換とは、お互いが公開パラメータを交換するだけで、同じ「共有秘密」を導出できる仕組みです。 TLS 1.3ではECDHE(楕円曲線ディフィー・ヘルマン)が使われます。 ECDHEでは両者が独立に同じ共有秘密を計算するため、秘密そのものはネットワーク上を流れません。 盗聴者が公開パラメータを見ても共有秘密を計算できないため、安全に鍵を共有できます。 上のツールのステップ5で、両者の鍵が中央に収束する様子が表示されます。
補足:RSA鍵交換(TLS 1.2以前)との違い — 古いRSA方式では、クライアントがプリマスターシークレットを生成し、サーバーの公開鍵で暗号化して送信していました。 この方式はサーバーの秘密鍵が漏洩すると過去の通信も解読されるため(前方秘匿性がない)、TLS 1.3で廃止されました。
セッション鍵(Session Key)
= 実際にデータを暗号化する鍵
セッション鍵は、共有秘密から導出される暗号化用の鍵です。この鍵で実際のHTTPリクエスト・レスポンスを暗号化します。 セッション鍵は一時的(ephemeral)であり、接続が終わると破棄されます。 これが「前方秘匿性」の根幹で、鍵が使い捨てだから過去の通信が安全に保たれます。
前方秘匿性(Forward Secrecy)
= 将来の鍵漏洩から過去を守る仕組み
前方秘匿性とは、サーバーの秘密鍵が将来漏洩しても、過去に記録された通信を解読できない性質です。 ECDHE鍵交換ではセッションごとに一時的な鍵ペアを生成・破棄するため、1つの鍵が破られても他のセッションに影響しません。 TLS 1.3ではこれが必須要件となり、RSA鍵交換(前方秘匿性なし)は廃止されました。
🔍
暗号スイートの読み方暗号スイート名は一見長くて難解ですが、実はパーツごとに意味があります。上のツールで選んだシナリオの暗号スイートを分解してみましょう。
TLS 1.3 形式
TLS_AES_128_GCM_SHA256
AES_128
暗号化アルゴリズム(128ビット鍵)
TLS 1.3では鍵交換にECDHEが必須のため、暗号スイート名には含まれません。
TLS 1.2 形式(参考)
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS 1.2では鍵交換と署名アルゴリズムも暗号スイート名に含まれるため、名前が長くなります。上のツールで「TLS 1.2接続」シナリオを選ぶと確認できます。
⚖️
TLS 1.2 vs TLS 1.3| 項目 | TLS 1.2(2008年〜) | TLS 1.3(2018年〜) |
|---|
| ハンドシェイク | 2往復(2-RTT) | 1往復(1-RTT) |
| 暗号スイート数 | 約37種類 | 5種類に厳選 |
| 前方秘匿性 | オプション(RSA可) | 必須(ECDHE/DHE) |
| 0-RTT再接続 | なし | あり(初回データ送信可) |
| 暗号化開始 | Finished後 | Server Hello直後 |
| レガシー暗号 | RC4, CBC, MD5 利用可 | 脆弱な暗号を全廃止 |
TLS 1.3はセキュリティとパフォーマンスの両方で大幅に改善されています。 上のツールで「TLS 1.2接続」シナリオに切り替えると、暗号スイート名の形式の違いを確認できます。 現在、Chrome・Firefox・Safari・Edgeなど主要ブラウザはすべてTLS 1.3をサポートしており、新規構築ではTLS 1.3を推奨します。
🔑
ECDHE鍵交換の仕組みECDHE(Elliptic Curve Diffie-Hellman Ephemeral)は、TLS 1.3で唯一認められた鍵交換アルゴリズムです。お互いの秘密鍵を一切送らずに、同じ共有秘密を作り出せるのが最大の特徴です。
💡 たとえ話:色の混ぜ合わせ
アリスとボブが共通の秘密の色を作りたいとします。 まず2人で公開の色(黄色)を決めます。 次にアリスは自分だけの秘密の色(赤)を混ぜてオレンジを作り、ボブは秘密の色(青)を混ぜて緑を作ります。 2人はオレンジと緑を交換し、それぞれ自分の秘密の色をさらに混ぜると、同じ茶色ができあがります。 盗聴者はオレンジと緑を見ても、元の秘密の色を分離できないため、茶色を作れません。 ECDHEはこれを楕円曲線の数学で実現しています。
ECDHE鍵交換のステップ
1
楕円曲線とベースポイントの合意
使用する楕円曲線(例:x25519やP-256)を決めます。 曲線上の基点 G は公開情報です。
2
各自が秘密鍵をランダム生成
クライアントは秘密鍵 a を、 サーバーは秘密鍵 b をランダムに生成します。 これらは一時的(Ephemeral)で、ハンドシェイク後に破棄されます。秘密鍵は絶対に送信しません。
3
公開鍵を計算して交換
クライアントは A = a × G(基点Gをa回足す)を計算し、 サーバーは B = b × G を計算します。 AとBは公開鍵としてClient Hello / Server Helloで交換します。 楕円曲線上では、AからaやBからbを逆算することは計算上不可能です(離散対数問題)。
4
共有秘密を独立に計算
クライアントは S = a × B = a × b × G を、 サーバーは S = b × A = b × a × G を計算します。 楕円曲線の性質により a × B = b × A が成り立つため、 両者は同じ共有秘密 S を得られます。この S からHKDF関数でセッション鍵を導出します。
RSA鍵交換との比較
RSA鍵交換(TLS 1.2以前)
1. クライアントがプリマスターシークレットをランダム生成
2. サーバーの公開鍵で暗号化して送信
3. サーバーが秘密鍵で復号
✗ 秘密鍵が漏洩すると過去の通信も解読可能
✗ 前方秘匿性なし → TLS 1.3で廃止
ECDHE鍵交換(TLS 1.3)
1. 両者が一時的な鍵ペアを独立に生成
2. 公開鍵のみを交換(秘密は送らない)
3. 各自が独立に共有秘密を計算
✓ 秘密鍵が漏洩しても過去の通信は安全
✓ 前方秘匿性あり(鍵は毎回使い捨て)
主な楕円曲線
x25519推奨
Daniel J. Bernsteinが設計。高速・定数時間処理でサイドチャネル攻撃に強い。TLS 1.3で最も使われる。Chrome・Firefox・Cloudflareが採用
P-256 (secp256r1)標準
NISTが標準化した曲線。AWS・金融機関など規制要件がある環境で使用。x25519より少し遅いが広くサポートされる
上のツールでシナリオを切り替えると、「鍵交換」欄に使用されている曲線(x25519 / P-256)が表示されます。 「HTTPS通常接続」ではx25519、「API通信」ではP-256が使われていることを確認してみてください。
📋
TLSハンドシェイクの手順(TLS 1.3)1
Client Hello を送信
クライアントが対応するTLSバージョン(TLS 1.3)、暗号スイートの候補リスト、鍵交換用のKey Shareパラメータ(例:x25519の公開鍵 32バイト)、ランダム値を送ります。SNI拡張で接続先ドメインも通知します。
2
Server Hello + 証明書を返信
サーバーが暗号スイートを1つ選び(例:TLS_AES_128_GCM_SHA256)、 自身のKey ShareパラメータとX.509証明書を返します。TLS 1.3ではこの時点から暗号化が始まります。
3
証明書を検証
クライアントが証明書チェーンをたどり、ルート認証局まで信頼できるか検証します。 ドメイン名の一致、有効期限、失効状態(CRL/OCSP)を確認します。 検証に失敗すると「この接続はプライベートではありません」という警告画面が表示されます。
4
鍵交換と共有秘密の導出
両者がECDHE(楕円曲線ディフィー・ヘルマン)で共有秘密(Shared Secret)を導出します。 Client HelloとServer Helloで交換したKey Shareパラメータから、両者が独立に同じ共有秘密を計算します(秘密自体は送信しません)。 この共有秘密からHKDF関数でセッション鍵を導出します。 ※ 古いRSA方式ではクライアントが秘密を生成してサーバーに送っていましたが、TLS 1.3ではECDHEが必須です。
5
Finished メッセージの交換
両者がFinishedメッセージを送り合い、ハンドシェイク全体のハッシュ(Verify Data)を検証します。 これにより、ハンドシェイク中のメッセージが改ざんされていないことを確認します。 検証に成功すると、暗号化通信の準備が完了します。
6
暗号化通信開始
TLSハンドシェイクが完了し、以降のすべてのHTTP通信はセッション鍵で暗号化されます。GET /index.htmlのようなHTTPリクエストも、TLSレコードで包まれた暗号文として送信されます。 ブラウザのアドレスバーに🔒が表示され、安全な通信が確立されたことを示します。
🔗
証明書チェーンと信頼モデルサーバー証明書の信頼性は、「証明書チェーン」という階層構造で確認されます。 ブラウザが直接信頼するのはルート認証局だけで、中間の認証局を経由してサーバー証明書まで信頼が伝搬します。
ルート認証局(Root CA)
ブラウザやOSにあらかじめ組み込まれた信頼の起点。Chrome には約150のルートCAが登録されています。 自分自身の証明書に署名する「自己署名証明書」を持ちます。
↕ 署名
中間認証局(Intermediate CA)
ルートCAの代わりに証明書を発行する認証局。ルートCAの秘密鍵を使う頻度を減らし、セキュリティを高めます。 Let's Encrypt R3やDigiCert SHA2 EV CAがこれにあたります。
↕ 署名
サーバー証明書(End-Entity Certificate)
Webサイトが実際に使う証明書。ドメイン名(example.com)や組織名が記載されます。 中間CAの秘密鍵で署名されており、クライアントは中間CA → ルートCAと辿って信頼性を確認します。 上のツールの「サーバー」パネルで証明書チェーンを確認できます。
🛡️
HTTP vs HTTPSHTTP(暗号化なし)
- ✗ データが平文で送信される
- ✗ パスワードが盗聴可能
- ✗ なりすましを検出できない
- ✗ データの改ざんを検出できない
- ✗ Chromeで「保護されていない通信」と表示
HTTPS(TLS暗号化)
- ✓ データがAES等で暗号化される
- ✓ パスワードは暗号文として送信
- ✓ 証明書でサーバーの身元を確認
- ✓ MACでデータの改ざんを検出
- ✓ ブラウザに🔒マークが表示
現在のWebではHTTPSがデフォルトです。 Google検索のランキング要因にもなっており、Let's Encryptにより無料で証明書を取得できます。 公開Wi-Fiなどの安全でないネットワークでも、TLSにより通信内容は保護されます。