网络知识大全
RFC 精读 · Application · Proposed Standard

RFC 8446

The Transport Layer Security (TLS) Protocol Version 1.3 —— 和 1.2 比,握手更短、删掉静态 RSA/DH、ServerHello 之后加密。实验室样本就是 ClientHello。

编号 / 标题
RFC 8446 · The Transport Layer Security (TLS) Protocol Version 1.3
发布
August 2018 · E. Rescorla
状态
Proposed Standard(不是 STD 编号)
关系
Obsoletes RFC 5246(TLS 1.2)、50776961 · Updates 57056066 · Obsoleted by RFC 9846(2026-07,同名 1.3 修订)
原文
rfc-editor HTML · 纯文本 · datatracker
实验室样本
TLS ClientHello(通常 TCP/443 载荷)
读这一篇的目标:能在 Wireshark 里指着 ClientHello 说出“真正的版本在哪个扩展、密钥材料在哪个扩展、为什么 Record 层还写着 0x0303”。不要把证书说成“用公钥加密网页”。
§1.2 Major Differences from TLS 1.2

1.3 砍掉了什么、加了什么

   -  The list of supported symmetric encryption algorithms has been
      pruned of all algorithms that are considered legacy.  Those that
      remain are all Authenticated Encryption with Associated Data
      (AEAD) algorithms.  The cipher suite concept has been changed to
      separate the authentication and key exchange mechanisms from the
      record protection algorithm (including secret key length) and a
      hash to be used with both the key derivation function and
      handshake message authentication code (MAC).

   -  A zero round-trip time (0-RTT) mode was added, saving a round trip
      at connection setup for some application data, at the cost of
      certain security properties.

   -  Static RSA and Diffie-Hellman cipher suites have been removed; all
      public-key based key exchange mechanisms now provide forward
      secrecy.

   -  All handshake messages after the ServerHello are now encrypted.
      The newly introduced EncryptedExtensions message allows various
      extensions previously sent in the clear in the ServerHello to also
      enjoy confidentiality protection.

   -  The key derivation functions have been redesigned.  The new design
      allows easier analysis by cryptographers due to their improved key
      separation properties.  The HMAC-based Extract-and-Expand Key
      Derivation Function (HKDF) is used as an underlying primitive.

   -  The handshake state machine has been significantly restructured to
      be more consistent and to remove superfluous messages such as
      ChangeCipherSpec (except when needed for middlebox compatibility).

   -  Elliptic curve algorithms are now in the base spec, and new
      signature algorithms, such as EdDSA, are included.  TLS 1.3
      removed point format negotiation in favor of a single point format
      for each curve.

[……节选页眉,下接 RSA-PSS / 版本协商 / PSK]

   -  Other cryptographic improvements were made, including changing the
      RSA padding to use the RSA Probabilistic Signature Scheme
      (RSASSA-PSS), and the removal of compression, the Digital
      Signature Algorithm (DSA), and custom Ephemeral Diffie-Hellman
      (DHE) groups.

   -  The TLS 1.2 version negotiation mechanism has been deprecated in
      favor of a version list in an extension.  This increases
      compatibility with existing servers that incorrectly implemented
      version negotiation.

   -  Session resumption with and without server-side state as well as
      the PSK-based cipher suites of earlier TLS versions have been
      replaced by a single new PSK exchange.

注解

对照 1.2,先记五条硬差异:

1. 只剩 AEAD(AES-GCM、ChaCha20-Poly1305)。CBC+HMAC、RC4 从套件表里消失。

2. TLS 1.3 删除静态 RSA/DH。不能再“用服务器证书公钥加密 premaster”。基于公钥的密钥交换提供前向保密,但纯 PSK 的 psk_ke 例外;0-RTT 数据也不具前向保密(§2.2、§4.2.9、Appendix E.1.3)。证书只做身份。

3. ServerHello 之后加密。线上外层记录只见 ContentType = Application Data;配置握手流量密钥解密之后,才能看到内部的 EncryptedExtensions / Certificate / Finished 等握手类型。

4. ChangeCipherSpec 不再是协议步骤,只在兼容中间盒时当伪装发出。

5. 版本协商搬家:不要再读 Record / legacy_version 的 0x0303,去读 supported_versions

套件名字也变了。1.2 的 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 把密钥交换、认证、对称、哈希捆在一起;1.3 的 TLS_AES_128_GCM_SHA256 只描述记录保护和 HKDF 哈希。认证与密钥交换改由扩展(signature_algorithms、key_share、psk)决定。

§2 Figure 1

完整 1-RTT 握手

       Client                                           Server

Key  ^ ClientHello
Exch | + key_share*
     | + signature_algorithms*
     | + psk_key_exchange_modes*
     v + pre_shared_key*       -------->
                                                  ServerHello  ^ Key
                                                 + key_share*  | Exch
                                            + pre_shared_key*  v
                                        {EncryptedExtensions}  ^  Server
                                        {CertificateRequest*}  v  Params
                                               {Certificate*}  ^
                                         {CertificateVerify*}  | Auth
                                                   {Finished}  v
                               <--------  [Application Data*]
     ^ {Certificate*}
Auth | {CertificateVerify*}
     v {Finished}              -------->
       [Application Data]      <------->  [Application Data]

              +  Indicates noteworthy extensions sent in the
                 previously noted message.

              *  Indicates optional or situation-dependent
                 messages/extensions that are not always sent.

              {} Indicates messages protected using keys
                 derived from a [sender]_handshake_traffic_secret.

              [] Indicates messages protected using keys
                 derived from [sender]_application_traffic_secret_N.

               Figure 1: Message Flow for Full TLS Handshake

   The handshake can be thought of as having three phases (indicated in
   the diagram above):

   -  Key Exchange: Establish shared keying material and select the
      cryptographic parameters.  Everything after this phase is
      encrypted.

   -  Server Parameters: Establish other handshake parameters
      (whether the client is authenticated, application-layer protocol
      support, etc.).

[……节选页眉,下接 Authentication 阶段]

   -  Authentication: Authenticate the server (and, optionally, the
      client) and provide key confirmation and handshake integrity.

注解

1.2 典型要 2-RTT(ClientHello → ServerHello+Certificate+… → ClientKeyExchange+CCS+Finished → CCS+Finished)。1.3 把客户端的密钥份额提前放到 ClientHello 的 key_share 里,服务器立刻能算出握手密钥,所以一轮往返之后就可以开始应用数据(服务器甚至可以在自己的 Finished 之后立刻发 Application Data)。

三个阶段对应图上的 Key Exch / Server Params / Auth。花括号 {} 是握手流量密钥保护,方括号 [] 才是应用流量密钥。实验室里你能明文读完的,通常只到 ClientHello 和 ServerHello。

常见 HTTPS:客户端不发证书;服务器发 Certificate + CertificateVerify + Finished。CertificateVerify 证明“我持有证书对应的私钥”,不是“用私钥加密数据”。

§4.1.2 ClientHello

结构体:实验室样本的骨架

      struct {
          ProtocolVersion legacy_version = 0x0303;    /* TLS v1.2 */
          Random random;
          opaque legacy_session_id<0..32>;
          CipherSuite cipher_suites<2..2^16-2>;
          opaque legacy_compression_methods<1..2^8-1>;
          Extension extensions<8..2^16-1>;
      } ClientHello;

注解

字段顺序就是线上顺序。外面还包着 TLS Record(ContentType=22 handshake,legacy record version 常常也是 0x0303)和 Handshake 头(msg_type=1 ClientHello,3 字节长度)。

实验室对照时按这个清单勾:

legacy_version 固定 0x0303。不是“客户端最高只到 1.2”。

random 32 字节,贡献握手新鲜度(handshake freshness)并进入 transcript;不要把它单独说成“防重放”。

legacy_session_id 1.3 里不再表示老式会话恢复。兼容模式(中间盒)会放 32 字节非空值,让看起来像 1.2 会话。

cipher_suites 只是客户端 offer。0x1301 / 0x1302 / 0x1303 出现在 ClientHello 里,只说明客户端愿意谈这些 1.3 套件;最终版本与套件以 ServerHello(及其中的 supported_versions)为准。

legacy_compression_methods 必须是单字节 0(null)。再谈压缩,服务器必须 abort。

extensions 才是 1.3 的真正内容:supported_versions(必有,含 0x0304)、key_share(X25519 等公钥)、signature_algorithmsserver_name(SNI)、application_layer_protocol_negotiation(h2 / http/1.1)。没有 supported_versions,对端会把它当 1.2 ClientHello 谈。

legacy_version

故意写成 1.2 的原因

   legacy_version:  In previous versions of TLS, this field was used for
      version negotiation and represented the highest version number
      supported by the client.  Experience has shown that many servers
      do not properly implement version negotiation, leading to "version
      intolerance" in which the server rejects an otherwise acceptable
      ClientHello with a version number higher than it supports.  In
      TLS 1.3, the client indicates its version preferences in the
      "supported_versions" extension (Section 4.2.1) and the
      legacy_version field MUST be set to 0x0303, which is the version
      number for TLS 1.2.  TLS 1.3 ClientHellos are identified as having
      a legacy_version of 0x0303 and a supported_versions extension
      present with 0x0304 as the highest version indicated therein.
      (See Appendix D for details about backward compatibility.)

注解

历史上客户端把“我会的最高版本”写在 version 字段,不少服务器看到比自己高的号码就直接断开——版本不耐受。1.3 把协商搬进扩展,外壳继续假装 1.2,中间盒和老服务器才肯把包往下传。

易误解:Wireshark 概要栏写 TLSv1.2 或 Record Version 0x0303,就断定这不是 1.3。先展开 ClientHello,找 supported_versions: TLS 1.3 (0x0304)

版本号口诀:SSL 3.0 = 0x0300,TLS 1.0 = 0x0301,1.1 = 0x0302,1.2 = 0x0303,1.3 = 0x0304。

§2.3 0-RTT

省一趟往返的代价

   IMPORTANT NOTE: The security properties for 0-RTT data are weaker
   than those for other kinds of TLS data.  Specifically:

   1.  This data is not forward secret, as it is encrypted solely under
       keys derived using the offered PSK.

   2.  There are no guarantees of non-replay between connections.
       Protection against replay for ordinary TLS 1.3 1-RTT data is
       provided via the server's Random value, but 0-RTT data does not
       depend on the ServerHello and therefore has weaker guarantees.
       This is especially relevant if the data is authenticated either
       with TLS client authentication or inside the application
       protocol.  The same warnings apply to any use of the
       early_exporter_master_secret.

注解

0-RTT 用上次的 PSK 在 ClientHello 之后立刻发送应用数据,省掉 1-RTT。它不具前向保密,连接之间也没有非重放保证。规范要求仅发送应用 profile 明确标为可安全重放的数据;幂等不自动等于安全(§8、Appendix E.5)。

服务器可以无视 early_data,退回普通 1-RTT。看到被拒不要当成握手失败。

抓包对照

实验室样本是 TCP 三次握手之后的第一条应用载荷:TLSv1.3 Record Layer / Handshake Protocol: Client Hello。过滤器 tls.handshake.type == 1

Record: ContentType 0x16 (handshake) legacy_record_version 0x0301 或 0x0303 length Handshake: msg_type 0x01 (client_hello) length (3 bytes) ClientHello 字节顺序: 03 03 legacy_version = TLS 1.2 32-byte random 00 或 20 + session_id legacy_session_id 00 xx + cipher suites 常含 13 01 / 13 02 / 13 03 01 00 compression = null 00 xx + extensions 必有 supported_versions = 03 04 常见 key_share, server_name, alpn tcpdump: tcp port 443 (不要用 PSH 过滤 ClientHello) Wireshark: tls.handshake.type == 1 tls.handshake.extensions.supported_version == 0x0304 tls.handshake.extensions_server_name

考点与易错点

  1. ClientHello 里的 0x1301–1303 和 supported_versions 只是客户端 offer;最终版本看 ServerHello。legacy_version 外壳仍是 0x0303。
  2. TLS 1.3 删除静态 RSA/DH;基于公钥的密钥交换提供前向保密,但纯 PSK 的 psk_ke 例外,0-RTT 数据也不具前向保密。
  3. ServerHello 之后握手消息加密。1.2 的明文证书在 1.3 抓包里消失。
  4. 套件名只描述 AEAD+HKDF 哈希;密钥交换和签名算法在扩展里。
  5. 压缩必须是 null。1.3 去掉了记录层压缩(CRIME 一类攻击的背景)。
  6. 0-RTT 仅发送应用 profile 明确标为可安全重放的数据;幂等不自动等于安全。服务器拒绝 0-RTT 仍可完成 1-RTT 握手。