TLSハンドシェイク早見表

✅ TLS 1.2 における RSA方式の鍵交換の流れ

▼ 1. クライアント Hello

  • クライアントはまず、サーバに「ClientHello」メッセージを送る。
  • ここには以下が含まれる:
    • サポートするTLSのバージョン
    • サポートする暗号スイート(例:RSA、AESなど)
    • 乱数(クライアントランダム)
    • その他オプション情報

▲ 2. サーバ Hello

  • サーバは「ServerHello」メッセージで応答する。
  • サーバの選択した:
    • TLSバージョン
    • 暗号スイート
    • サーバの乱数(サーバランダム)

▲ 3. サーバ証明書の送信

  • サーバは自分の公開鍵証明書(X.509証明書)をクライアントに送信。
    • 証明書の中に、サーバのRSA公開鍵が入っている。
    • 証明書は認証局(CA)によって署名されていて、クライアントはその正当性を検証する。

▼ 4. クライアントが Pre-Master Secret を生成

  • クライアントは、ランダムなPre-Master Secret(48バイトのランダム値)を生成。
  • そして、そのPre-Master Secretをサーバの公開鍵でRSA暗号化する。

▼ 5. クライアントキー交換

  • 暗号化されたPre-Master Secretを「ClientKeyExchange」メッセージとしてサーバに送信。

▲ 6. サーバが Pre-Master Secret を復号

  • サーバは自分のRSA秘密鍵で復号し、Pre-Master Secretを得る。

▼▲ 7. 共通鍵の生成

  • クライアントとサーバはそれぞれ、以下の情報から同じ共通鍵(セッション鍵)を導出:
    • Pre-Master Secret
    • クライアントランダム
    • サーバランダム
  • これにより、共通の暗号鍵・MAC鍵などが生成される。

この3つの値を材料として、TLS 1.2では:

Markdown
マスターシークレット = PRF(Pre-Master Secret, "master secret", ClientRandom + ServerRandom)

という手順でマスターシークレットが生成されます。

さらにこのマスターシークレットから、

Markdown
セッション鍵(共通鍵) = PRF(Master Secret, "key expansion", ServerRandom + ClientRandom)

のようにして、実際に通信に使う暗号鍵・MAC鍵などが生成されます。
※この際の"master secret""key expansion"は固定の文字列で、どの用途の鍵を作るのか区別するために使われます。

✅【PRFとは】

  • Pseudo-Random Function(擬似乱数生成関数)
  • TLSの仕様の中で、「こういうアルゴリズムで計算しなさい」と定義されています。
  • TLS1.2では**HMAC(SHA-256などのハッシュ関数)**をベースに実装されています。

▼▲ 8. Finished メッセージで確認

  • その後、クライアントとサーバは、共通鍵を使って「Finished」メッセージを交換し、お互いに正しい鍵が共有できたことを確認。

✅ 【まとめ図】

Markdown
1. ClientHello (クライアント乱数 + 暗号スイート)
2. ServerHello (サーバ乱数 + 暗号スイート選択)
3. サーバ証明書 (RSA公開鍵含む)
4. Pre-Master Secret 生成
5. Pre-Master Secret を公開鍵で暗号化し送信
6. サーバが秘密鍵で復号
7. Pre-Master Secret + 両者の乱数 → 共通鍵
8. Finishedメッセージ交換 → 暗号通信開始

✅ 【ポイント】

  • クライアントだけがPre-Master Secretを生成する。
  • サーバは復号するだけで、自分では鍵は作らない。
  • Pre-Master Secretと乱数2つから鍵素材(共通鍵)ができる。
  • RSA方式はサーバ秘密鍵が漏れると過去のPre-Master Secretも解読できるためForward Secrecyが無い

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

✅【TLS 1.2 における DHE 鍵交換の流れ】

✅【前提:DHEとは】

  • DHE(Ephemeral Diffie-Hellman)は、セッションごとに一時的な鍵(エフェメラル鍵)を使って共通鍵を生成する仕組み。
  • Forward Secrecy(前方秘匿性)があり、もしサーバの秘密鍵が漏れても過去の通信は解読されない。

🔵 ① クライアント Hello

  • クライアントはClientHelloをサーバに送信。
  • そこに:
    • サポートする暗号スイート(例:TLS_DHE_RSA_WITH_AES_128_CBC_SHA など)
    • TLSのバージョン
    • クライアントのランダム値(クライアントランダム)
      などを含める。

🌑② サーバ Hello

  • サーバはServerHelloを返し、
    • 選択した暗号スイート(ここではDHEを含むもの)
    • TLSバージョン
    • サーバランダム
      を送る。

🌑③ サーバ証明書の送信

  • サーバは、自身の公開鍵証明書(X.509証明書)を送信。
  • 証明書にはRSAの公開鍵などが入っていて、「サーバの正当性確認のため」に使われる。
  • (DHEでは、このRSA鍵で署名するために使う)

🌑④ サーバのDHEパラメータ送信(ServerKeyExchange)

  • サーバは以下の情報を送信:
    • p(素数)
    • g(生成元)
    • サーバのDHE公開値:g^b mod p(bはサーバの秘密値)
    • これらに対するRSA署名(サーバ証明書の秘密鍵で署名)

こうすることで、「このDHEパラメータは正当なサーバが送ったものだよ」と証明している。


🔵 ⑤ クライアントのDHEパラメータ送信

  • クライアントは、ランダムな秘密値aを選び、
    • クライアントの公開値:g^a mod p
      を計算し、ClientKeyExchangeメッセージでサーバに送る。

🔵🌑 ⑥ 双方が共通鍵素材(Pre-Master Secret)を計算

  • クライアント側:
Markdown
(g^b mod p)^a mod p
= g^(ab) mod p
  • サーバ側:
Markdown
(g^a mod p)^b mod p
= g^(ab) mod p

→ クライアントとサーバが同じ値(g^(ab) mod p)を得る。これがPre-Master Secretになる。


🔵🌑 ⑦ Pre-Master Secret + ランダム値 → 共通鍵生成

  • 双方はPre-Master Secretと
    • クライアントランダム
    • サーバランダム
      をPRF関数に入れて、マスターシークレットを生成。
  • さらにマスターシークレットから、セッション鍵(共通鍵)が計算される。

🔵🌑 ⑧ Finished メッセージ交換

  • 共通鍵を用いて、Finishedメッセージを暗号化して交換
  • お互いの鍵が一致していれば復号が成功し、ここから安全な通信が始まる。

✅【まとめ図】

Markdown
1. ClientHello(クライアントランダム、対応暗号スイート)
2. ServerHello(サーバランダム、選択暗号スイート)
3. Certificate(サーバの証明書)
4. ServerKeyExchange(p, g, g^b mod p, 署名)
5. ClientKeyExchange(g^a mod p)
6. 両者で g^(ab) mod p を計算 → Pre-Master Secret
7. Pre-Master Secret + ランダム2種 → PRF → マスターシークレット
8. マスターシークレット → 共通鍵(セッション鍵)
9. Finishedメッセージ交換

  • RSA方式と違い、Pre-Master Secretは両者が計算で得る
  • サーバ証明書のRSA鍵は「署名検証」のみで、暗号化には使わない。
  • Forward Secrecyあり(秘密鍵が漏れてもg^bが漏れない限り安全)

タイトルとURLをコピーしました