0 / 9
TLS 1.2 ハンドシェイク(TLS 1.2 Handshake)
TLS(Transport Layer Security)は、ブラウザとWebサーバーのように初めて出会った二者が安全に通信できるようにするプロトコルだ。データをやり取りする前に、二者はまずハンドシェイクというメッセージ交換を行う。ここで暗号化の方式を決め、サーバーが本物かを確かめ、一緒に使う鍵を作る。この図はその順序をTLS 1.2で示す。大きくは交渉、サーバー認証、鍵交換、完了確認の四つのまとまりだ。ハンドシェイクが終わると、暗号化された通信が始まる。
例: ブラウザ(Client)がショッピングサイトのWebサーバー(Server)に初めて接続する。
1 / 9
Client → Server: ClientHello
Clientが先に声をかける。対応している最も高いTLSバージョンと、使える暗号スイートの一覧、そして乱数Client Randomを送る。乱数は秘密ではなくそのまま流れる値で、接続ごとに鍵が変わるようにするために使う。暗号スイートは、鍵交換・認証・暗号化に使うアルゴリズムを1セットにまとめたものだ。
2 / 9
Server → Client: ServerHello
ServerがClientの一覧から双方が使える暗号スイートを1つ選び、TLSのバージョンも決めて伝える。自分の乱数Server Randomも一緒に送る。ここまでが交渉だ。
3 / 9
Server → Client: Certificate
Serverが自分の証明書を送る。証明書には、Serverの公開鍵と、その鍵がこのドメインのものだという認証局(CA)の署名が入っている。ServerHelloDoneも送り、helloの段階のメッセージはここで終わりだと知らせる。
4 / 9
Client: 証明書の検証
Clientが証明書を自分で検査する。証明書の署名を、中間CAをたどってブラウザに最初から入っているルートCAまで確かめ、有効期間が切れていないか、接続先のドメインと証明書のドメインが同じかも見る。証明書が失効していないかも、CRLやOCSPで確かめられる。1つでも違えば警告を出すか接続を止める。すべて合えば、この公開鍵は本物のServerのものだと信じる。
5 / 9
Client → Server: ClientKeyExchange
Clientがセッション鍵(この接続だけで使う対称鍵)の材料になる秘密の値Premaster secretを作る。この値をServerの公開鍵で暗号化して送る。途中で横取りされても、Serverの秘密鍵がなければ復号できない。
6 / 9
ClientとServer: セッション鍵の計算
Serverが自分の秘密鍵でPremaster secretを復号する。これで双方がClient Random、Server Random、Premaster secretを持つ。それぞれが同じ計算をする。3つの値からマスターシークレットを作り、そこから実際の暗号化に使う鍵を取り出す。こうして双方が同じセッション鍵を持ち、セッション鍵そのものはネットワークに流さない。
7 / 9
Client → Server: ChangeCipherSpec, Finished
ClientがChangeCipherSpecで、これからはセッション鍵で暗号化して送ると知らせる。続けてFinishedを送る。Finishedには、ここまでにやり取りしたハンドシェイクメッセージ全体の検証値が入っていて、セッション鍵で暗号化した最初のメッセージでもある。
8 / 9
Server → Client: ChangeCipherSpec, Finished
ServerもChangeCipherSpecとFinishedを同じ方法で送る。受け取った検証値が自分で計算した値と一致すれば、交渉の内容が途中で書き換えられておらず、同じセッション鍵を持っているということだ。正しいFinishedを作るにはPremaster secretを復号できなければならないので、秘密鍵を持つ本物のServerだという最後の確認にもなる。一致しなければ接続を切る。
9 / 9
暗号化通信の開始
ハンドシェイクが終わった。これからやり取りするデータ(Application Data)は、セッション鍵で暗号化する。暗号化と復号に同じ鍵を使う対称鍵方式なので速い。遅い公開鍵暗号は、データの暗号化には使わず、鍵を決めるときに使う。