Handshake Protocol
Handshake Protocol は、TLS 接続で利用する暗号化パラメータのネゴシエーション及び認証を行うプロトコルである。
Handshake Protocol のメッセージの先頭にはヘッダが付き、その中では
- HandshakeType: メッセージの種類
- length: メッセージの長さ
が定義されている。
struct {
HandshakeType msg_type;
unit24 length;
HandshakeMessage message
} Handshake;
下記に、最も一般的な形態であるサーバ認証モード (認証されていないクライアントと認証されるサーバーとの間のハンドシェイク) を示す。
- ClientHello: クライアントが新規のハンドシェイクを開始し、希望する暗号スイートや鍵交換の方法などをサーバに送信
- ServerHello: サーバが接続で使うパラメータを選択し、それをクライアントに送信
- Certificate: サーバからクライアントへ X.509 証明書チェーンを運ぶ
- ServerKeyExchange: 鍵交換に必要な付加的なデータを運ぶ
- ServerHelloDone: 予定していたハンドシェイクをすべて送信した時にサーバから送る合図
- ClientKeyExchange: 鍵交換に必要な情報をクライアントから送信するためのメッセージ
- ChangeCipherSpec: 接続で使うパラメータを組み立てるのに十分な情報をすでに手に入れたこと、暗号鍵を生成したこと、これから暗号処理へ移行することを相手に伝えるメッセージ
- Finished: サーバから送信及び受信したハンドシェイクメッセージの MAC を送信する 上記のうち、ClientHello、ServerHello、及び Finished について以下で詳しく見ていくこととしよう。
ClientHello
新規のハンドシェイクで常に最初に送信されるのが ClientHello メッセージ。 クライアントは、これにより自分が希望するパラメータ群とその優先度をサーバに伝える。 下記に ClientHello のメッセージ例を示す。
Secure Sockets Layer
TLSv1.2 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22)
Version: TLS 1.0 (0x0301)
Length: 512
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 508
Version: TLS 1.2 (0x0303)
Random
GMT Unix Time: Mar 8, 2018 15:05:33.000000000 JST
Random Bytes: be09be15500323950e7be72de26887bc66093e245d0911be...
Session ID Length: 0
Cipher Suites Length: 112
Cipher Suites (56 suites)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)
Cipher Suite: TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 (0xc032)
Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02e)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
Cipher Suite: TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 (0xc031)
Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02d)
Cipher Suite: TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 (0x00a3)
Cipher Suite: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x009f)
Cipher Suite: TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 (0x00a2)
Cipher Suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x009e)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (0xc024)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
Cipher Suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 (0xc02a)
Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 (0xc026)
Cipher Suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA (0xc00f)
Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA (0xc005)
Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (0x006b)
Cipher Suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 (0x006a)
Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x0039)
Cipher Suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA (0x0038)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xc023)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)
Cipher Suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 (0xc029)
Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 (0xc025)
Cipher Suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA (0xc00e)
Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA (0xc004)
Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (0x0067)
Cipher Suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 (0x0040)
Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033)
Cipher Suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA (0x0032)
Cipher Suite: TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (0xc012)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (0xc008)
Cipher Suite: TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA (0xc00d)
Cipher Suite: TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA (0xc003)
Cipher Suite: TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (0x0088)
Cipher Suite: TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA (0x0087)
Cipher Suite: TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA (0x0045)
Cipher Suite: TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA (0x0044)
Cipher Suite: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (0x0016)
Cipher Suite: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA (0x0013)
Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)
Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003d)
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003c)
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
Cipher Suite: TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (0x0084)
Cipher Suite: TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (0x0041)
Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)
Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)
Compression Methods Length: 1
Compression Methods (1 method)
Compression Method: null (0)
Extensions Length: 355
Extension: server_name
Type: server_name (0x0000)
Length: 38
Server Name Indication extension
Server Name list length: 36
Server Name Type: host_name (0)
Server Name length: 33
Server Name: logs.ap-northeast-1.amazonaws.com
Extension: ec_point_formats
Type: ec_point_formats (0x000b)
Length: 4
EC point formats Length: 3
Elliptic curves point formats (3)
Extension: elliptic_curves
Type: elliptic_curves (0x000a)
Length: 10
Elliptic Curves Length: 8
Elliptic curves (4 curves)
Extension: SessionTicket TLS
Type: SessionTicket TLS (0x0023)
Length: 0
Data (0 bytes)
Extension: signature_algorithms
Type: signature_algorithms (0x000d)
Length: 32
Signature Hash Algorithms Length: 30
Signature Hash Algorithms (15 algorithms)
Extension: Heartbeat
Type: Heartbeat (0x000f)
Length: 1
Mode: Peer allowed to send requests (1)
Extension: Padding
Type: Padding (0x0015)
Length: 242
Padding Data: 000000000000000000000000000000000000000000000000...
ServerHello
サーバが接続で用いるパラメータを選択し、それをクライアントに返答する。構造は ClientHellot と同様だが、各フィールドにはサーバが決定したパラメータが入る。
Secure Sockets Layer
TLSv1.2 Record Layer: Handshake Protocol: Server Hello
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 89
Handshake Protocol: Server Hello
Handshake Type: Server Hello (2)
Length: 85
Version: TLS 1.2 (0x0303)
Random
GMT Unix Time: May 8, 2066 05:57:56.000000000 JST
Random Bytes: 09e73aed2cca189f26171fe412c12ce754bee28e7e2efcdf...
Session ID Length: 32
Session ID: 8554ac73465abb661a4804ad27ae306059a6f1f7ae80e761...
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
Compression Method: null (0)
Extensions Length: 13
Extension: renegotiation_info
Type: renegotiation_info (0xff01)
Length: 1
Renegotiation Info extension
Extension: ec_point_formats
Type: ec_point_formats (0x000b)
Length: 4
EC point formats Length: 3
Elliptic curves point formats (3)
Finished
ハンドシェイクが完了したという合図。Finished メッセージは暗号化されており、ネゴシエーション済みの MAC によって完全性が保証されている。 Finished メッセージには verify_data というフィールドがあり、このフィールドはクライアントとサーバのそれぞれが受信したハンドシェイクメッセージのすべてをハッシュ化し、その値とマスターシークレットを組み合わせて計算したものである。
鍵交換
ハンドシェイクで最も面白いところは鍵交換である。(らしい)
TLS ではマスターシークレットと呼ばれる 48 バイトの鍵をサーバとクライアントで共有する。このマスターシークレットがセッションのセキュリティを支えているが、鍵交換の目的はこのマスターシークレットを生成するためのプリマスターシークレットを生成することにある。
TLS では多様な証明書や公開鍵アルゴリズム、鍵交換アルゴリズムをサポートしている。今回は RSA 鍵交換アルゴリズムについて紹介する。
RSA 鍵交換のアルゴリズムは単純。
- クライアントがプリマスターシークレット ( 48 バイトの乱数 ) を生成し、それをサーバの公開鍵で暗号化し、ClientKeyExchange メッセージに入れてサーバに送信
- サーバがこのメッセージを秘密鍵で複合することにより、サーバがプリマスターシークレットを取得
- 複合したプリマスターシークレットからマスターシークレットを生成する
ただし、RSA 鍵交換の簡潔さは欠点でもある。プリマスターシークレットはサーバの公開鍵で暗号化されるが、数年間そのまま残ることもある。対応する秘密鍵があれば誰でもプリマスターシークレットを複合して同一のマスターシークレットを生成し、セッションの乗っ取りを行える。