SSL/TLS通信について、2026年3月時点では TLS 1.2 は減少傾向にあり(ただし既存システムでは依然として利用されている)、現在は TLS 1.3 の利用が増加しており、主要なサービスでは主流になりつつあります。
今更ですが TLS 1.2 と TLS 1.3 の違いを比較してみたいと思います。
1. TLS 1.2
1.1. シーケンス図
1.2. 処理説明
1.2.1. ClientHello(クライアント → サーバ)
目的
- 接続条件の提示
実施内容
- 使用可能な暗号スイートの提示
- TLSバージョン提示
- ランダム値(ClientRandom)送信
ポイント
ここでは交渉を開始しただけで、まだ鍵は共有していません。
1.2.2. ServerHello(サーバ → クライアント)
目的
- 暗号方式の決定
実施内容
- 使用する暗号スイートを選択
- ServerRandom を送信
1.2.3. Certificate(サーバ → クライアント)
目的
- サーバの身元提示
実施内容
- サーバ証明書(+中間証明書)を送る
- ブラウザはここで証明書検証を開始
1.2.4. ServerKeyExchange(※ECDHEなどの場合)(サーバ → クライアント)
※重要
証明書の検証(CAによる正当性確認)と、ServerKeyExchange における署名(秘密鍵の所持証明)は別の検証です。
両方が成立して初めて、正当なサーバと判断されます。
RSA暗号化鍵交換の場合、 ServerKeyExchange は不要で、署名は行われません。
目的
- 鍵交換情報の提示+本人確認
実施内容
- ECDHEの公開鍵などを送信
- その内容にサーバの秘密鍵で署名
- 署名対象には ClientRandom / ServerRandom / 鍵交換パラメータ が含まれる
重要
TLS1.2(ECDHEなど)では、鍵交換パラメータに対する署名によってサーバの本人確認が行われます。(RSA鍵交換ではこのステップは存在しません。)
1.2.5. ServerHelloDone(サーバ → クライアント)
目的
- サーバ側の送信終了の合図
TLS1.2の設計上の区切り(後続メッセージ開始の合図)です。
1.2.6. ClientKeyExchange(クライアント → サーバ)
目的
- 鍵交換のための情報送信
実施内容
■ RSA鍵交換
- Pre-Master Secret を生成し、サーバ証明書の公開鍵で暗号化して送信
■ ECDHE
- クライアント側の公開鍵を送る
※補足:
現在はECDHEが主流です。
RSA鍵交換は前方秘匿性(Forward Secrecy)がないため、現在は非推奨であり、新規システムではほぼ使用されません。ただし既存システムでは一部残っている場合があります。
RSA鍵交換では ClientKeyExchange で Pre-Master Secret を暗号化して送信し、ServerKeyExchange は不要です。
1.2.7. ChangeCipherSpec(クライアント → サーバ)
目的
- 暗号通信への切り替え宣言
これ以降は共通鍵で暗号化します。
1.2.8. Finished(クライアント → サーバ)
目的
- ハンドシェイク整合性の検証
実施内容
- マスターシークレットとハンドシェイクメッセージのハッシュから PRFにより計算された verify_data を送信
- サーバが検証
改ざん検知をします。
1.2.9. ChangeCipherSpec(サーバ → クライアント)
目的
- 暗号通信への切り替え宣言
サーバも暗号化へ移行します。
1.2.10. Finished(サーバ → クライアント)
目的
- ハンドシェイク整合性の検証
実施内容
- マスターシークレットとハンドシェイクメッセージのハッシュから PRFにより計算された verify_data を送信
- クライアントが検証
改ざん検知をします。
2. TLS 1.3
TLS 1.3 は「高速化」と「セキュリティ強化」を目的に設計されています。
TLS 1.3 ではハンドシェイクが 1RTT で完了し、TLS 1.2(2RTT)と比較して通信開始までの遅延が削減されています。
また、TLS 1.3 では、暗号スイートの構成が簡素化され、RC4 や SHA1 などの安全でないアルゴリズムは廃止されています。
2.1. シーケンス図
2.2. 処理説明
2.2.1. ClientHello(クライアント → サーバ)
目的
- 交渉+鍵共有の開始
実施内容
- 暗号スイート提示
- 鍵共有(ECDHE公開鍵 + group 情報)送信
- ランダム値送信
TLS 1.2との最大の違いで、最初から鍵共有を開始します。
TLS 1.3 では Forward Secrecy を満たす鍵共有方式(DH/ECDHE)が必須となり、常に前方秘匿性(Forward Secrecy)が確保されます。
RSA単独暗号化鍵交換は TLS 1.3 ではサポートされません。
2.2.2. ServerHello(サーバ → クライアント)
目的
- 鍵共有の成立(共有秘密の導出が可能になる)
実施内容
- 暗号スイート決定
- サーバ側の公開鍵送信
この時点で共有秘密(shared secret)の計算が可能になります。
TLS 1.3 では、共有秘密から HKDF による鍵導出(key schedule)で以下の 3 段階の鍵が生成されます:
- early secret(0-RTT 用)
- handshake secret(ハンドシェイクメッセージ暗号化用)
- application secret(アプリケーションデータ暗号化用)
ServerHello受信時点で handshake traffic secret が導出され、EncryptedExtensions 以降のメッセージは暗号化されます。
2.2.3. EncryptedExtensions(サーバ → クライアント)
目的
- 拡張ネゴシエーション結果の通知
実施内容
- ALPN(暗号化通信で使うアプリケーション層プロトコルを交渉)(HTTP/2 など)
- SNI(どのサーバ名(証明書)を使うかを決める拡張)関連の応答
- その他拡張機能の確定情報を送信
このメッセージ以降は暗号化されて送信されます。
2.2.4. Certificate(サーバ → クライアント)
目的
- サーバ証明書の提示
TLS1.2と同じです。
2.2.5. CertificateVerify(サーバ → クライアント)
※重要
証明書検証(CAによる正当性の確認)と、CertificateVerify による「秘密鍵の所持証明」は別の検証です。
- 証明書検証 → 「この証明書は信頼できるCAが発行したか」
- CertificateVerify → 「サーバがその証明書に対応する秘密鍵を本当に持っているか」
この両方が成立して初めて、「正当なサーバ」と判断されます。
目的
- サーバの本人確認(明確化)
実施内容
- ハンドシェイクメッセージ全体(Transcript)に対して署名
- サーバの秘密鍵を使う
TLS 1.2 では ServerKeyExchange に署名として埋め込んでいましたが、TLS 1.3 ではCertificateVerify という独立メッセージになりました。
署名対象はハンドシェイク全体の Transcript であり、正確にサーバの秘密鍵を所有していることを証明します。
2.2.6. Finished(サーバ → クライアント)
目的
- ハンドシェイクの完全性検証
実施内容
- ハンドシェイクメッセージ全体(Transcript)のハッシュに対する検証値(verify_data)を送信・検証
- verify_data は、handshake traffic secret から HKDF-Expand により導出された finished_key を用いた HMAC で計算される
- サーバが送信し、クライアントが検証
2.2.7. Finished(クライアント → サーバ)
目的
- ハンドシェイクの完全性検証
実施内容
- ハンドシェイクメッセージ全体(Transcript)のハッシュに対する検証値(verify_data)を送信・検証
- verify_data は、handshake traffic secret から HKDF-Expand により導出された finished_key を用いた HMAC で計算される
- クライアントが送信し、サーバが検証
3. TLS 1.2 と TLS 1.3 の違い(まとめ)
TLS 1.2 と TLS 1.3 の大きな違いとしては、TLS 1.2 のような独立した鍵交換(key exchange)は独立フェーズとしては廃止され、TLS 1.3 では ClientHello / ServerHello 内の鍵共有(key share)と、その後の鍵導出(key schedule)に再設計されたことです。
全体的な違いは以下となります。
| TLS1.2 | TLS1.3 | 何をしているか |
|---|---|---|
| ClientHello | ClientHello(+鍵共有) | 暗号方式+(TLS1.3は鍵共有も) |
| ServerHello | ServerHello(+鍵共有) | 暗号方式決定+鍵共有 |
| Certificate | Certificate | サーバ証明書送信 |
| ServerKeyExchange | (廃止) | 鍵交換(TLS1.2のECDHEなどで必要だった鍵交換情報送信。TLS1.3ではHello内で統合) |
| ServerHelloDone | (廃止) | 区切り(不要になった) |
| ClientKeyExchange | (廃止) | 鍵交換(→Hello内の鍵共有に統合され、その後鍵導出として実現) |
| ChangeCipherSpec | (互換用途で残存) | 暗号化開始(自動化・no-op化) |
| Finished | Finished | ハンドシェイク整合性確認 |
| (なし) | CertificateVerify | 本人確認(明確化) |
それぞれの違いを見ると以下の通りです。
-
① ClientHello
- TLS 1.2
ClientHello - TLS 1.3
ClientHello(+鍵共有)
- TLS 1.2
ここが最大の進化ポイント
-
② ServerHello
- TLS 1.2
ServerHello - TLS 1.3
ServerHello(+鍵共有)
- TLS 1.2
この時点で共有秘密(shared secret)の計算が可能になり、その後の鍵導出(HKDF)によってハンドシェイク鍵などが生成されます。
-
③ 鍵交換(TLS1.2)と鍵共有+鍵導出(TLS1.3)(一番大きな変更)
- TLS 1.2
鍵交換(key exchange)
ServerKeyExchange
ClientKeyExchange - TLS 1.3
(なし)
- TLS 1.2
TLS 1.2 では後から鍵交換(key exchange)を行うのに対し、TLS 1.3 では Hello メッセージ内で鍵共有(key share)により共有秘密を生成し、その後 HKDF による鍵導出(key schedule)によってハンドシェイク鍵やアプリケーション鍵が生成されます。
-
④ サーバ証明書
- 共通
Certificate
- 共通
ここは同じです。
-
⑤ 本人確認(重要な違い)
- TLS 1.2
ServerKeyExchange の中で署名(ECDHE時) - TLS 1.3
CertificateVerify
- TLS 1.2
TLS 1.2 ではわかりにくい場所になりましたが、TLS 1.3では専用メッセージで明確化されています。
-
⑥ ServerHelloDone
- TLS 1.2
ServerHelloDone - TLS 1.3
(なし)
- TLS 1.2
TLS 1.2 では「サーバ側終わり」の合図がありましたが、TLS 1.3では不要になりました。
-
⑦ ChangeCipherSpec
- TLS 1.2
ChangeCipherSpec - TLS 1.3
(互換用途で残存)
- TLS 1.2
TLS 1.2 では「暗号開始」の合図がありましたが、TLS 1.3 では「暗号化開始」の明示的な合図は不要になりました。
ただし、互換性維持(中間機器対策)のため、ダミーメッセージとして送信される場合があります(意味的には no-op)。
- ⑧ Finished
- 共通
Finished
- 共通
ハンドシェイクの整合性チェックは共通です。
以上