TLS 版本协商

当前所有的 TLS/SSL 版本:

  • SSL 2.0 (废弃)
  • SSL 3.0 (废弃)
  • TLS 1.0
  • TLS 1.1
  • TLS 1.2
  • TLS 1.3

无论是客户端还是服务器端,同时支持多个协议版本非常常见,那么不可避免的需要进行版本协商。 不过,这并不难,因为TLS协议已经制定了协商的方法。

由于当前 SSL2.0 已经没人使用,并且它的数据包格式和其他版本也不兼容,版本协商不可用,这里不在讨论 SSL2.0。


SSL 握手阶段需要通过交换 ClientHello 和 ServerHello 来协商当前即将建立的 TLS/SSL 版本。


TLS 1.3 协议下的协商


TLS1.3 扩展:supported_versions


这个扩展用来包含一个或多个 TLS 版本信息, 它可以在 ClientHelloServerHello 中使用。 在 ClientHello 中表示客户端支持的 TLS 版本. 在 Server Hello 中,表示服务器端想使用的 TLS 版本.

当扩展中包含多个 TLS 版本信息时, 排位越靠前,优先级越高。

当 ClientHello 中不包含 Supported_versions 扩展时,服务器端按照 ClientHello.legacy_version中的值(这个值可以是 0x0304 或者更新的版本)来进行 TLS 版本协商。

当 ClientHello 中包含 supported_versions 扩展时,服务器忽略ClientHello.legacy_version 中的值, 而是按照 supported_versions 中的值进行 TLS 版本协商。

如果服务器选择了一个 TLS 1.3 之前的版本,那么 ServerHello.version 必须设置为选择的版本,并且不能包含 supported_versions 扩展。

如果服务器选择使用 TLS 1.3,那么 ServerHello.legacy_version 必须设置为 0x0303 (TLS 1.2), 并且设置 supported_versions 扩展中包含 0x0304 (TLS 1.3).


协商方式


对于 TLS1.3 的客户端,如果它想连接到一个不支持TLS1.3的服务器,那么它需要发送一个 TLS1.3 ClientHello, 其中的版本号(ClientHello.legacy_version)为 0x0303(TLS), 同时需要设置正确的supported_versions扩展。 如果服务器不支持 TLS13,它将会给客户端回复一个包含低版本号的 ServerHello. 如果服务器支持 TLS 13,继续进行即可。

如果客户端不支持服务器端选择的协议版本,客户端必须中止握手,并发送 "protocol_version" alert.

对于 TLS1.3 服务器端来讲,它也可以接受一个携带一个低版本号的 ClientHello,如果有supported_versions 扩展, 根据这个扩展内容来协商最终版本号。如果没有该扩展,服务器则选择ClientHello.legacy_versionTLS 1.2 两者中较小的。例如,服务器支持 TLS 1.0, TLS 1.1, TLS 1.2, legacy_version 是 TLS 1.0, 那服务器应该选择 TLS 1.0.

如果没有supported_versions 扩展并且服务器只支持比ClientHello.legacy_version 大的协议版本,服务器必须中止握手,并发送 protocol_version alert.

现实问题:

部分 TLS 服务器端的实现没有严格按照 RFC 规定来做,他们在收到不认识的 TLS ClientHello 扩展 或者 ClientHello 版本号的时候,会中止握手,导致版本协商失败。

例子 1:客户端支持 TLS1.3和TLS1.2, 服务器只支持 TLS1.2
// Client Hello (忽略了其他字段)
Transport Layer Security
    TLSv1.2 Record Layer: Handshake Protocol: Client Hello
        Content Type: Handshake (22)
        Version: TLS 1.0 (0x0301)
        Length: 516
        Handshake Protocol: Client Hello
            Handshake Type: Client Hello (1)
            Length: 512
            Version: TLS 1.2 (0x0303)
            Extension: supported_versions (len=7)
                Type: supported_versions (43)
                Length: 7
                Supported Versions length: 6
                SUpported Version: Reserved (GREASE) (0x4a4a)
                Supported Version: TLS 1.3 (0x0304)
                Supported Version: TLS 1.2 (0x0303)
        ....

ClientHello 中包含 supported_versions: TLS 1.3, TLS1.2. 按照 TLS1.3 优先,TLS1.2 次之的顺序排列。

注意: Record.Version: TLS 1.0 是为了兼容性。

// Server Hello
Transport Layer Security
    TLSv1.2 Record Layer: Handshake Protocol: Server Hello
        Content Type: Handshake (22)
        Version: TLS 1.2 (0x0303)
        Length: 84
        Handshake Protocol: Server Hello
            Handshake Type: Server Hello (2)
            Length: 80
            Version: TLS 1.2 (0x0303)
            Random:
            Session ID Length: 0
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
            Compression Method: null (0)
            Extensions Length: 40
            Extension: renegotiation_info (len=1)
            Extension: server_name (len=0)
            Extension: ec_point_formats (len=4)
            Extension: session_ticket (len=0)
            Extension: application_layer_protocol_negotiation (len=11)
            Extension: extended_master_secret (len=0)

由于服务器不支持 TLS 1.3, 因此选择了 TLS 1.2. 此时 Record.Version 和 Handshake.Version 都设置为 TLS 1.2.

响应中并没有包含 supported_versions 扩展。

例子 2:客户端支持 TLS1.3, 服务器支持 TLS1.3
// Client Hello
Transport Layer Security
    TLSv1.3 Record Layer: Handshake Protocol: Client Hello
        Content Type: Handshake (22)
        Version: TLS 1.0 (0x0301)
        Length: 240
        Handshake Protocol: Client Hello
            Handshake Type: Client Hello (1)
            Length: 236
            Version: TLS 1.2 (0x0303)
            Extension: supported_versions (len=3)
                Type: supported_versions (43)
                Length: 3
                Supported Versions length: 2
                Supported Version: TLS 1.3 (0x0304)
            ....
// Server Hello
Transport Layer Security
    TLSv1.3 Record Layer: Handshake Protocol: Server Hello
        Content Type: Handshake (22)
        Version: TLS 1.2 (0x0303)
        Length: 146
        Handshake Protocol: Server Hello
            Handshake Type: Server Hello (2)
            Length: 142
            Version: TLS 1.2 (0x0303)
            Extension: supported_versions (len=2)
                Type: supported_versions (43)
                Length: 2
                Supported Version: TLS 1.3 (0x0304)
            ...

服务器选择了 TLS 1.3, 此时 Record.Version 和 Handshake.Version 都设置为 TLS 1.2.

使用 ServerHello 中 supported_versions 扩展告知客户端它选择了 TLS 1.3.


TLS 1.2 及以前版本下的版本协商


对于 TLS1.2 客户端来说,他们通常发送一个正常的 TLS 1.2 的 ClientHello 消息,其中 ClientHello.client_version的值为 {3,3}(TLS 1.2). 如果服务器端不支持 TLS1. 2, 服务器会发送一个包含更低 TLS 版本的 ServerHello给客户端。 如果支持,那么正常进行即可。

如果客户端不支持服务器端选择的协议版本,客户端必须中止握手,并发送 "protocol_version" alert.

如果 TLS 服务器收到一个包含更高版本号的 ClientHello , 它必须回复一个 ServerHello, 其中的版本号是服务器端支持的最高版本号。

服务器端可能会收到一个包含比自己最高版本号低的版本号的ClientHello , 此时服务器可以回复一个ServerHello, 其中的版本号是服务器端支持的版本号中不大于ClientHello.client_version的最大版本号。

例子 3:客户端支持 TLS1.1, 服务器只支持 TLS1.0
// Client Hello
Transport Layer Security
    TLSv1 Record Layer: Handshake Protocol: Client Hello
        Content Type: Handshake (22)
        Version: TLS 1.1 (0x0302)
        Length: 138
        Handshake Protocol: Client Hello
            Handshake Type: Client Hello (1)
            Length: 134
            Version: TLS 1.1 (0x0302)
        ....

由于客户端支持的最高 TLS 版本就是 TLS 1.1. 此时 Record.Version 和 Handshake.Version 都设置为 TLS 1.1.

// Server Hello
Transport Layer Security
    TLSv1 Record Layer: Handshake Protocol: Server Hello
        Content Type: Handshake (22)
        Version: TLS 1.0 (0x0301)
        Length: 81
        Handshake Protocol: Server Hello
            Handshake Type: Server Hello (2)
            Length: 77
            Version: TLS 1.0 (0x0301)
            ....

由于服务器端不支持 TLS 1.1, 所以服务器选择了 TLS 1.0, 这里 Record.Version 和 Handshake.Version 都设置为 TLS 1.0.


参考链接


ref: https://www.rfc-editor.org/rfc/rfc5246#appendix-E.1

ref: https://www.rfc-editor.org/rfc/rfc8446.html#appendix-D


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *