TLS协商

6 阅读3分钟
  • TLS 握手过程
    在 TLS 握手中,客户端和服务器协商出共同的加密算法和密钥,从而建立安全通信连接。握手过程通常包括 ClientHello、ServerHello、证书交换、密钥交换、Change Cipher Spec 和 Finished 消息的交换。

  • 密钥交换方式

    • RSA 密钥交换
      客户端直接利用服务器证书中的 RSA 公钥加密 Pre-Master Secret 发送给服务器,不需要额外传递密钥交换参数,因此不需要发送 ServerKeyExchange 消息。
    • 临时密钥交换(Ephemeral Key Exchange,如 DHE/ECDHE)
      每次握手都会使用一次性的临时密钥参数,能够实现前向安全性(即使将来服务器私钥泄露,也无法解密以前的通信)。在这种方式中,服务器必须通过 ServerKeyExchange 消息提供临时的公钥参数和签名,供客户端进行 Diffie-Hellman 运算,共同生成共享密钥。
  • Finished 消息 是 TLS 握手过程中的最后一步,起到了至关重要的验证作用。其主要特点和作用包括:

    • 完整性验证
      Finished 消息包含了一个经过加密的摘要(或称为“验证数据”),该摘要是基于整个握手过程中交换的所有消息计算出来的。
      这可以确保整个握手过程中的信息未被篡改,双方都基于相同的握手记录生成了相同的摘要。

    • 使用新密钥加密
      Finished 消息是在双方发送 Change Cipher Spec 消息之后,用新协商的加密密钥进行加密的。这保证了消息本身的安全性,并确认双方已经切换到新加密状态。

    • 握手完成标志
      当客户端和服务器成功交换并验证 Finished 消息后,TLS 握手过程就被认为是完整且安全的。接下来,双方可以开始使用协商好的密钥加密实际的应用数据。

    简而言之,Finished 消息是一个用来确认 TLS 握手期间所有协商和交换的数据都已正确且安全传输的验证信号。


sequenceDiagram
    participant C as 客户端
    participant S as 服务器
    participant CA as 证书颁发机构 (CA)
    
    Note over C,S: <b>1. ClientHello</b>
    C->>S: ClientHello<br/>(TLS 版本、加密套件、Client Random 等)
    
    Note over S,C: <b>2. ServerHello + 证书</b>
    S->>C: ServerHello<br/>(选定的TLS版本、加密套件、Server Random 等)
    S->>C: 服务器证书 (Certificate)
    alt 需要临时密钥交换 (如 ECDHE)
        S->>C: ServerKeyExchange
    end
    S->>C: ServerHelloDone
    
    Note over C,CA: <b>3. 验证服务器证书</b>
    C->>CA: 使用根证书验证服务器证书的合法性
    CA-->>C: 验证结果
    
    Note over C,S: <b>4. ClientKeyExchange</b>
    C->>S: ClientKeyExchange<br/>(用服务器公钥加密的 Pre-Master Secret)
    
    Note over C,S: <b>5. Change Cipher Spec & Finished(客户端)</b>
    C->>S: ChangeCipherSpec<br/>(通知服务器切换到新协商好的加密参数)
    C->>S: Finished<br/>(用新密钥加密的握手校验消息)
    
    Note over S,C: <b>6. Change Cipher Spec & Finished(服务器)</b>
    S->>C: ChangeCipherSpec
    S->>C: Finished
    
    Note over C,S: <b>7. 握手完成,开始安全通信</b>
    C-->>S: <b>后续应用数据</b>(使用对称密钥加密)

流程要点

  1. ClientHello

    • 客户端发送支持的 TLS 版本、加密套件列表、客户端随机数(Client Random)等信息给服务器。
  2. ServerHello + 服务器证书

    • 服务器从客户端支持的选项中选出一个加密套件和 TLS 版本,返回 ServerHello(包括服务器随机数),并附上服务器证书。
    • 如果使用临时密钥交换(如 ECDHE),会额外发送 ServerKeyExchange 消息。
    • 服务器以 ServerHelloDone 表示初步协商完成。
  3. 验证服务器证书

    • 客户端使用本地或系统内置的 CA 根证书来验证服务器证书的合法性和有效期、域名匹配等。
  4. ClientKeyExchange

    • 客户端生成 Pre-Master Secret,并使用服务器公钥(或临时密钥交换信息)加密后发送给服务器。 或通过双方 Diffie-Hellman 运算生成的临时密钥数据。
    • 客户端与服务器随后根据两端的随机数 (Client Random、Server Random) 和 Pre-Master Secret 共同派生出对称密钥。
  5. Change Cipher Spec & Finished(客户端)

    • 客户端发送 ChangeCipherSpec(一种“状态切换”信号,表示发送方已经切换到新的加密状态),告诉服务器后续数据将使用协商好的对称加密。
    • 紧接着发送 Finished 消息,用新协商的密钥加密,验证握手过程的完整性。
  6. Change Cipher Spec & Finished(服务器)

    • 服务器也发送 ChangeCipherSpec 切换到新加密方式。
    • 然后发送 Finished 消息,完成服务器端的握手确认。
  7. 握手完成

    • 双方成功交换并验证 Finished 消息后,TLS 握手正式结束。
    • 之后客户端与服务器使用相同的对称密钥进行加密通信,实现机密性与完整性保护。