TLS 1.3のハンドシェイク:接続が確立するまでの流れを解説
まえがき
TLS はデータ通信を暗号化して盗聴を防いだり、改ざんを検出するための技術であり、現代の情報社会において必須技術です。
前身である SSL から大幅に内容が変わったため TLS と名前が変わりましたが、SSL という呼び名が広く知られていたため SSL/TLS と呼ばれることもあります。
TLS は様々な場合・状況が考慮されておりすべてを説明するのは大変です。
なので、今回は普段私達がサイトに安全に接続するまでの一般的な場合に絞って説明します。
TLS1.3におけるハンドシェイクの具体的な流れ
説明を簡単にするために下記のような状況を想定します。
- サーバー側のみを認証する(一方向認証)
- TLSハンドシェイクにおいて、やり直しや失敗が起きない
- 事前共有鍵(PSK)は使わない
では、TLS接続が確立するまでの流れについて、鍵交換と認証の2つのフェーズに分けて説明していきます(本来は鍵交換、サーバーパラメーター、認証の3つのフェーズがありますが、サーバーパラメーターは省略します)。
鍵交換フェーズ

TLS接続が確立するまでの双方のやり取りのことをTLSハンドシェイクと呼び、TLSハンドシェイクでまず行われるのは鍵交換です。
鍵交換フェーズではTLSハンドシェイクの一部およびアプリケーションのデータのやり取りを暗号化するための共通鍵が計算されます。
TLSの開始にあたって、クライアント側は鍵交換アルゴリズムであるECDHEまたはDHEのアルゴリズムを用いて秘密鍵と公開鍵を生成します。
このとき、クライアント側がサポートするすべての鍵交換アルゴリズムについて生成する必要はなく、サーバー側で選ぶと推測できるものを一つ以上生成します。
続いて、サーバー側へClientHelloを送ります。
ClientHelloには下記の情報が含まれています。
- 暗号スイートのリスト(認証付き暗号アルゴリズムとハッシュ関数のペアのリスト)
- 鍵交換アルゴリズムのリスト + 公開鍵Pc
- 署名アルゴリズムのリスト
それぞれの用途として、認証付き暗号アルゴリズムはメッセージの暗号化・認証のために、ハッシュ関数は鍵導出関数やハンドシェイクの内容のハッシュ値(トランスクリプトハッシュ)の計算のために、署名アルゴリズムはサーバー証明書や CeriticateVerify の検証のために使われます。
なお、TLS1.3 からサーバー証明書用の署名アルゴリズムを個別で指定できるようになっていますが、それを省略した場合はサーバー証明書の検証も CeriticateVerify の検証もここで指定したものから選ばれます。
NOTE
ClientHelloに限らず、以降の説明では着目したいデータだけ示していることに注意してください(本来はもっと含まれるデータがあります)。
ClientHelloを受け取ったサーバー側は、それに含まれる暗号スイート(認証付き暗号アルゴリズムとハッシュ関数のペアのリスト)から一つ、署名アルゴリズムから一つ、鍵交換アルゴリズムのリストから一つを選びます。
このとき、選んだ鍵交換アルゴリズムにクライアント側の公開鍵がない場合は再送依頼(HelloRetryRequest)を送りますが、今回はサポートしているものに公開鍵もあるとします。
その鍵交換アルゴリズムを用いて、秘密鍵 Ss と公開鍵 Ps を生成します。
サーバー側にはクライアントの公開鍵 Pc とサーバーの秘密鍵 Ss がある状態です。
この2つを用いて共有シークレットを計算します。
そして、この共有シークレットをもとに、さきほど選んだハッシュ関数を用いて鍵導出が行われ共通鍵を生成します(細部を省略していますが、共通鍵の導出にはもっと多くの処理が行われています。単に共有シークレットを入力とした鍵導出関数の出力が共通鍵となるわけではありません)。
この共通鍵と認証付き暗号アルゴリズムを用いて、TLSにおける暗号化は行われます。
また、この共通鍵はセッション鍵とも呼ばれます。
NOTE
上記の説明では共有シークレットを鍵導出関数に与えれば共通鍵が得られる印象を与えてしまいますが、本来は下記のようにもっと多くの処理がされています。(RFC8446 の 7.1)共有シークレットから生成されるのは共有鍵の元となる値で、これもシークレットと呼ばれます。
特に、ハンドシェイクのメッセージの暗号化に使うものはハンドシェイクシークレット(Handshake Secret)、
アプリケーションのメッセージの暗号化に使うものはマスターシークレット(Master Secret)と呼ばれます。
さらに、そのシークレット自体もすぐ共通鍵の生成に使われるのではなく、
クライアントがデータを送る時に使うもの、サーバーがデータを送るときに使うものでさらに別々にシークレットが導出され、
それぞれ client または server が頭に付く名前となっており、このシークレットが共通鍵の生成に使用されます。
NOTE
図に示されているように、TLSハンドシェイクの暗号化用の共通鍵とアプリケーションデータの暗号化用の共通鍵が別々に生成されていることに注意してください。
サーバー側の内部で行われる処理はここまでで、続いてクライアント側へServerHelloを送ります。
ServerHelloには下記の情報が含まれています。
- 選択した暗号スイート(認証付き暗号アルゴリズムとハッシュ関数のペアのリスト)
- 選択した鍵交換アルゴリズム + 公開鍵Ps
ServerHelloを送ることで、クライアント側でもサーバー側と同じ共有シークレットが計算できることになります。
つまり、以降のTLSハンドシェイクの内容は暗号化して送信することができるということです。
実際、TLS1.3では以降のやり取りが暗号化されて通信されることになります。(TLS1.2以前はアプリケーションのデータの通信から暗号化されていました)
以上が、鍵交換フェーズになります。
認証フェーズ

ServerHelloを送った直後ではありますが、フェーズが変わり認証フェーズに入ります。
認証フェーズでは、サーバー証明書を用いたサーバーの正当性の確認とTLSハンドシェイクのメッセージの整合性(改ざんされていないかなど)を確認します。
以降、共有シークレットから導出された共通鍵によって通信は暗号化されています。
(ServerHelloを送ったあと、)サーバー側では以下の情報を送ります。
- Certificate: サーバー証明書(正確には証明書チェーン)
- CertificateVerify: これまでのTLSハンドシェイクの内容(ClientHelloからCertificateまで)のハッシュ値(トランスクリプトハッシュ)をもとにしたデジタル署名を含む
- Finished: これまでのTLSハンドシェイクの内容にCertificateVerifyを加えたもの、すなわちこれまでやりとりのすべてのハッシュ値(トランスクリプトハッシュ)をもとにした認証タグ(MAC)を含む
- Application Data: アプリケーションのデータ
これらのメッセージを受信したクライアントは次の作業を行います。
Certificate, CertificateVerify, Finishedは暗号化された状態で送られてくるので、共有シークレットから導出した共通鍵を用いて復号します。
その後、それぞれの内容を検証し、問題がなければ クライアント側も Finished を送り、認証フェーズを終えます。
以上が、TLS1.3におけるハンドシェイクの流れになります。
確認問題
問題1
問題: TLSハンドシェイクはフェーズが存在しますが、その名前はなんでしょう。
答え: 鍵交換フェーズ、認証フェーズ
問題2
問題: TLSハンドシェイクが始まると、クライアントとサーバーはTLS接続におけるパラメータについて交渉します。そのパラメータにはなにがあるでしょう(複数あります)。
答え: 暗号スイート(認証付き暗号アルゴリズムとハッシュ関数)、鍵交換アルゴリズム、署名アルゴリズム
問題3
問題: TLS接続ではメッセージを暗号化する際に共通鍵が用いられます。共通鍵自体を送らなくても、クライアントとサーバーが同じ共通鍵を持つことができるのはなぜですか。
答え: 鍵交換アルゴリズム(ECDHE/DHE)により、互いの公開鍵を交換すれば、自身の秘密鍵と相手の公開鍵から全く同じ共有シークレットが生成できる。加えて、鍵の導出には互いが決定したハッシュ関数が用いられる。共有シークレットとハッシュ関数はお互いに同じ情報を双方が持っているので、それらを用いて共通鍵を計算することができるため。
参考
IETF | Internet Engineering Task Force
RFC 8446 – The Transport Layer Security (TLS) Protocol Version 1.3
https://datatracker.ietf.org/doc/html/rfc8446
IPA 独立行政法人 情報処理推進機構
TLS 暗号設定ガイドライン
https://www.ipa.go.jp/security/crypto/guideline/gmcbt80000005ufv-att/ipa-cryptrec-gl-3001-3.1.1.pdf
デイビット・ウォン. 現代暗号技術入門
https://amzn.to/4mDGh6Q
Jean-Philippe Aumasson. Serious Cryptography
https://amzn.to/4mEwei0
Jean-Philippe Aumasson. 暗号技術 実践活用ガイド(上記の翻訳版)
https://amzn.to/46UOOhi
コメント