SSL / TLS ( 2 ) ~ プロトコル ~

July 17, 2017

Handshake Protocol

Handshake Protocol は、TLS 接続で利用する暗号化パラメータのネゴシエーション及び認証を行うプロトコルである。
Handshake Protocol のメッセージの先頭にはヘッダが付き、その中では

  1. HandshakeType: メッセージの種類
  2. length: メッセージの長さ

が定義されている。

struct {
  HandshakeType msg_type;
  unit24 length;
  HandshakeMessage message
} Handshake;

下記に、最も一般的な形態であるサーバ認証モード (認証されていないクライアントと認証されるサーバーとの間のハンドシェイク) を示す。

f:id:shiro_kochi:2018××××××××:plain:w100:left

  1. ClientHello: クライアントが新規のハンドシェイクを開始し、希望する暗号スイートや鍵交換の方法などをサーバに送信
  2. ServerHello: サーバが接続で使うパラメータを選択し、それをクライアントに送信
  3. Certificate: サーバからクライアントへ X.509 証明書チェーンを運ぶ
  4. ServerKeyExchange: 鍵交換に必要な付加的なデータを運ぶ
  5. ServerHelloDone: 予定していたハンドシェイクをすべて送信した時にサーバから送る合図
  6. ClientKeyExchange: 鍵交換に必要な情報をクライアントから送信するためのメッセージ
  7. ChangeCipherSpec: 接続で使うパラメータを組み立てるのに十分な情報をすでに手に入れたこと、暗号鍵を生成したこと、これから暗号処理へ移行することを相手に伝えるメッセージ
  8. 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 鍵交換のアルゴリズムは単純。

  1. クライアントがプリマスターシークレット ( 48 バイトの乱数 ) を生成し、それをサーバの公開鍵で暗号化し、ClientKeyExchange メッセージに入れてサーバに送信
  2. サーバがこのメッセージを秘密鍵で複合することにより、サーバがプリマスターシークレットを取得
  3. 複合したプリマスターシークレットからマスターシークレットを生成する

ただし、RSA 鍵交換の簡潔さは欠点でもある。プリマスターシークレットはサーバの公開鍵で暗号化されるが、数年間そのまま残ることもある。対応する秘密鍵があれば誰でもプリマスターシークレットを複合して同一のマスターシークレットを生成し、セッションの乗っ取りを行える。


 © 2023, Dealing with Ambiguity