TLSでは暗号化通信を始める前に、通信相手の認証や暗号化通信に使う鍵情報の共有、使用する暗号アルゴリズムの決定などを実施する。これらのやりとりはハンドシェイクと呼ばれる。
TLSをマスターするには、ハンドシェイクを理解することが不可欠だ。そこでこのパートでは、TLS 1.2と1.3のハンドシェイクを解説する。TLS 1.3ではTLS 1.2から大きく変わるので要注意だ。
TLS 1.2のやりとりは2往復
まずはTLS 1.2におけるハンドシェイクを具体的に見ていこう(図2-1)。端末などのクライアントは、TLSによる接続要求として「Client Hello▼」メッセージ▼を最初に送信する。Client Helloには、端末が利用可能なTLSのバージョンや暗号スイート▼などの情報が含まれている。
Client Helloを受け取ったWebサーバーは、Client Helloに含まれる候補の中から、利用するTLSのバージョンと暗号スイートを選択し、「Sever Hello」で端末に送信する。このSever Helloが接続受け付けの通知になる。
続いてWebサーバーは「Certificate」でサーバー証明書を送信。「Server Key Exchange」でサーバーの鍵情報を送る。この鍵情報を基に、暗号化通信で使う共通鍵などを作成する。そして最後に、サーバーからの最初のメッセージ群の送信完了を伝える「Server Hello Done」を送信する。Sever HelloからServer HelloDoneまでが、Client Helloに対する返事になる。つまりServerHello Doneまでで、1往復のやりとりが終了したことになる。
Server Hello Doneを受信した端末は、2往復目のやりとりを開始する。ここでは、プリマスターシークレット▼を作成し共有する。
プリマスターシークレットの作成方法は鍵交換の暗号アルゴリズムによって異なる。1つは端末がプリマスターシークレットを作成し、Certificateで送られたサーバー証明書に含まれる公開鍵で暗号化して、Client Key ExchangeでWebサーバーに送信する方法。もう1つは、Server Key Exchangeで送られた鍵情報と、Client Key Exchangeで送る鍵情報を使ってプリマスターシークレットを作成する方法である。いずれの場合でも、2往復目の最初ではClient Key Exchangeで鍵情報が送られることになる。
これによりプリマスターシークレットが共有され、それを基に端末とWebサーバーは鍵を作成する。具体的には、Client HelloとServer Helloでそれぞれ共有した乱数とプリマスターシークレットを組み合わせてマスターシークレットと呼ばれるデータを作成する。そしてそれを基に、通信を暗号化するセッション鍵、メッセージの認証に使用するMAC▼鍵、初期化ベクトル▼を作成する。
鍵を作成した端末は、次のメッセージから暗号化するという通知である「Change Cipher Spec」をWebサーバーへ送る。続いてハンドシェイクが完了した通知である「Finished」を暗号化して送る。
Finishedを受け取ったWebサーバーは、同様にChange Cipher Specを端末に送った後、暗号化したFinishedを送信。以降、データの暗号化通信を開始する。