TLS 1.3: Change Cipher Spec, Client Hello(再送信)

# Change Cipher Spec, Client Hello(再送信)

サーバから Hello Retry Requestと Change Cipher specが来た後、clientが再度 Client Helloを最送信するところのフローです。

| #    | src| dest   | type    | length | info           |
| ---- | ----------------- | ----------------- | ------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| 142  | \*\*localhost\*\* | example.com       | TLSv1.3 | 409    | Change Cipher Spec, Client Hello|
| 145  | example.com       | \*\*localhost\*\* | TCP     | 66     | 443 → 58364 \[ACK\] Seq=100 Ack=861 Win=68096 Len=0 TSval=2936265895 TSecr=107391639|

serverからackが来てますね。

ひとつずつ見ていきます。


# Change Cipher Spec

[server側のと同じく](https://qiita.com/uturned0/items/537368b4d4b8ffe52b19)、6bytesしかない小さなメッセージです。Change Cipher Specは TLS 1.2 では暗号化開始の合図だったようですが、TLS1.3では違うのかな。これはClienthelloを送り直す前に、お互いリセットし合う意味合いで送るんだろうか。


```yml
TLSv1.3 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec
    Content Type: Change Cipher Spec (20)
    Version: TLS 1.2 (0x0303)
    Length: 1
    Change Cipher Spec Message
```


# Client Hello (再送信)

[当初clientは鍵交換に x25519というカーブを要望しました](https://qiita.com/uturned0/items/44092e09321099506131) が、serverが secp256r1を使えと hello retry requestを返してきました。そこで、clientがsecp256r1を使う形で client helloを送り直す部分です。

```yml
TLSv1.3 Record Layer: Handshake Protocol: Client Hello
    Content Type: Handshake (22)
    Version: TLS 1.2 (0x0303)
    Length: 332
    Handshake Protocol: Client Hello
        Handshake Type: Client Hello (1)
        Length: 328
        Version: TLS 1.2 (0x0303)
        Random: a990959f0793ba1ff5a09d1a5eec06e87706c88ea969457fa59d9ba9dc0f0e32
        Session ID Length: 32
        Session ID: b1c8e600556b5561ceda33e4c9c0b59221e45d11fb5cc03de4c165861b34f642
        Cipher Suites Length: 32
        Cipher Suites (16 suites)
        Compression Methods Length: 1
        Compression Methods (1 method)
        Extensions Length: 223
        Extension: Reserved (GREASE) (len=0)
            Type: Reserved (GREASE) (64250)
            Length: 0
            Data: <MISSING>
        Extension: server_name (len=16)
            Type: server_name (0)
            Length: 16
            Server Name Indication extension
                Server Name list length: 14
                Server Name Type: host_name (0)
                Server Name length: 11
                Server Name: example.com
        Extension: extended_master_secret (len=0)
            Type: extended_master_secret (23)
            Length: 0
        Extension: renegotiation_info (len=1)
            Type: renegotiation_info (65281)
            Length: 1
            Renegotiation Info extension
                Renegotiation info extension length: 0
        Extension: supported_groups (len=10)
            Type: supported_groups (10)
            Length: 10
            Supported Groups List Length: 8
            Supported Groups (4 groups)
                Supported Group: Reserved (GREASE) (0xcaca)
                Supported Group: x25519 (0x001d)
                Supported Group: secp256r1 (0x0017)
                Supported Group: secp384r1 (0x0018)
        Extension: ec_point_formats (len=2)
            Type: ec_point_formats (11)
            Length: 2
            EC point formats Length: 1
            Elliptic curves point formats (1)
                EC point format: uncompressed (0)
        Extension: session_ticket (len=0)
            Type: session_ticket (35)
            Length: 0
            Data (0 bytes)
        Extension: application_layer_protocol_negotiation (len=14)
            Type: application_layer_protocol_negotiation (16)
            Length: 14
            ALPN Extension Length: 12
            ALPN Protocol
                ALPN string length: 2
                ALPN Next Protocol: h2
                ALPN string length: 8
                ALPN Next Protocol: http/1.1
        Extension: status_request (len=5)
            Type: status_request (5)
            Length: 5
            Certificate Status Type: OCSP (1)
            Responder ID list Length: 0
            Request Extensions Length: 0
        Extension: signature_algorithms (len=18)
            Type: signature_algorithms (13)
            Length: 18
            Signature Hash Algorithms Length: 16
            Signature Hash Algorithms (8 algorithms)
                Signature Algorithm: ecdsa_secp256r1_sha256 (0x0403)
                    Signature Hash Algorithm Hash: SHA256 (4)
                    Signature Hash Algorithm Signature: ECDSA (3)
                Signature Algorithm: rsa_pss_rsae_sha256 (0x0804)
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: SM2 (4)
                Signature Algorithm: rsa_pkcs1_sha256 (0x0401)
                    Signature Hash Algorithm Hash: SHA256 (4)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Algorithm: ecdsa_secp384r1_sha384 (0x0503)
                    Signature Hash Algorithm Hash: SHA384 (5)
                    Signature Hash Algorithm Signature: ECDSA (3)
                Signature Algorithm: rsa_pss_rsae_sha384 (0x0805)
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (5)
                Signature Algorithm: rsa_pkcs1_sha384 (0x0501)
                    Signature Hash Algorithm Hash: SHA384 (5)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Algorithm: rsa_pss_rsae_sha512 (0x0806)
                    Signature Hash Algorithm Hash: Unknown (8)
                    Signature Hash Algorithm Signature: Unknown (6)
                Signature Algorithm: rsa_pkcs1_sha512 (0x0601)
                    Signature Hash Algorithm Hash: SHA512 (6)
                    Signature Hash Algorithm Signature: RSA (1)
        Extension: signed_certificate_timestamp (len=0)
            Type: signed_certificate_timestamp (18)
            Length: 0
        Extension: key_share (len=71)
            Type: key_share (51)
            Length: 71
            Key Share extension
                Client Key Share Length: 69
                Key Share Entry: Group: secp256r1, Key Exchange length: 65
                    Group: secp256r1 (23)
                    Key Exchange Length: 65
                    Key Exchange: 042c60dacb51f9139a814981fe52c830f990fb739ba98ac993ef19b823cfb5be2ab0371f…
        Extension: psk_key_exchange_modes (len=2)
            Type: psk_key_exchange_modes (45)
            Length: 2
            PSK Key Exchange Modes Length: 1
            PSK Key Exchange Mode: PSK with (EC)DHE key establishment (psk_dhe_ke) (1)
        Extension: supported_versions (len=7)
            Type: supported_versions (43)
            Length: 7
            Supported Versions length: 6
            Supported Version: Reserved (GREASE) (0x2a2a)
            Supported Version: TLS 1.3 (0x0304)
            Supported Version: TLS 1.2 (0x0303)
        Extension: compress_certificate (len=3)
            Type: compress_certificate (27)
            Length: 3
            Algorithms Length: 2
            Algorithm: brotli (2)
        Extension: application_settings (len=5)
            Type: application_settings (17513)
            Length: 5
            ALPS Extension Length: 3
            Supported ALPN List
                Supported ALPN Length: 2
                Supported ALPN: h2
        Extension: Reserved (GREASE) (len=1)
            Type: Reserved (GREASE) (39578)
            Length: 1
            Data: 00
        [JA3 Fullstring: 771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-,29-23-24,0]
        [JA3: 47d0fb2dc82c86701e340aa1cca4b1c1]
```

## 2 つの Client Hello を Diff してみた

変わった部分は以下です。

左が最初の Client Hello, 右が再送信する Client Hello です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24737/8c92abbb-4837-908d-5aae-f5b105f79b00.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24737/c148f3a1-7723-c899-7137-103359c6779b.png)

大きく変わったのは やはり key_share のところです。server側の要望に合わせてあります。共有値(Key Exchange) は変わりましたが、TLS record自体の random は変わりませんでした。つまりTLS recordのヘッダ部分と、extentionは別々に管理されているということなんだろう。このひとつのTLS handshakeとしては共通してるので、TLS recordのrandomは変わらない。

```diff
--- first.txt	2022-08-13 17:15:57.000000000 +0900
+++ second.txt	2022-08-13 17:16:41.000000000 +0900
@@ -1,11 +1,12 @@
 TLSv1.3 Record Layer: Handshake Protocol: Client Hello
     Content Type: Handshake (22)
-    Version: TLS 1.0 (0x0301)
-    Length: 512
+    Version: TLS 1.2 (0x0303)
+    Length: 332
     Handshake Protocol: Client Hello
         Handshake Type: Client Hello (1)
-        Length: 508
+        Length: 328
         Version: TLS 1.2 (0x0303)
         Random: a990959f0793ba1ff5a09d1a5eec06e87706c88ea969457fa59d9ba9dc0f0e32
         Session ID Length: 32
@@ -30,7 +31,7 @@
             Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
         Compression Methods Length: 1
         Compression Methods (1 method)
-        Extensions Length: 403
+        Extensions Length: 223
         Extension: Reserved (GREASE) (len=0)
             Type: Reserved (GREASE) (64250)
             Length: 0
@@ -93,19 +94,15 @@
         Extension: signed_certificate_timestamp (len=0)
             Type: signed_certificate_timestamp (18)
             Length: 0
-        Extension: key_share (len=43)
+        Extension: key_share (len=71)
             Type: key_share (51)
-            Length: 43
+            Length: 71
             Key Share extension
-                Client Key Share Length: 41
-                Key Share Entry: Group: Reserved (GREASE), Key Exchange length: 1
-                    Group: Reserved (GREASE) (51914)
-                    Key Exchange Length: 1
-                    Key Exchange: 00
-                Key Share Entry: Group: x25519, Key Exchange length: 32
-                    Group: x25519 (29)
-                    Key Exchange Length: 32
-                    Key Exchange: ab83faa28c812c3237c264b8d213968dadf7450bcc0c69d9f37fe6775f1fe015
+                Client Key Share Length: 69
+                Key Share Entry: Group: secp256r1, Key Exchange length: 65
+                    Group: secp256r1 (23)
+                    Key Exchange Length: 65
+                    Key Exchange: 042c60dacb51f9139a814981fe52c830f990fb739ba98ac993ef19b823cfb5be2ab0371fâ¦
         Extension: psk_key_exchange_modes (len=2)
             Type: psk_key_exchange_modes (45)
             Length: 2
@@ -134,9 +131,5 @@
             Type: Reserved (GREASE) (39578)
             Length: 1
             Data: 00
-        Extension: padding (len=204)
-            Type: padding (21)
-            Length: 204
-            Padding Data: 000000000000000000000000000000000000000000000000000000000000000000000000â¦
-        [JA3 Fullstring: 771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0]
-        [JA3: cd08e31494f9531f560d64c695473da9]
+        [JA3 Fullstring: 771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-,29-23-24,0]
+        [JA3: 47d0fb2dc82c86701e340aa1cca4b1c1]
```


もうひとつ変わったのは TLS record version. TLS 1.0から1.2に変わっています。これは恐らく、 serverからの Hello Retry Requestが TLS1.2で返してきたからだと思われる。たぶん。

```yml
Transport Layer Security
    TLSv1.3 Record Layer: Handshake Protocol: Hello Retry Request
        Content Type: Handshake (22)
        Version: TLS 1.2 (0x0303)      <---- serverから返ってきたversion
```

clientは最初の client helloでは相手が tls 1.2 に対応してるかどうかもわからないので、tls1.0で始める（下位互換）風習があるんだろう。仕様もそれを許容するために、extension: supported_verions とかでversionを指定していってる昨今。




あとは [最初のClient hello](https://qiita.com/uturned0/items/44092e09321099506131) と同じなので、解読はいいかな。

---
↓ まとめページ
https://qiita.com/uturned0/items/a24828b9b3c25c1612b0