Skip to content

Encrypted Client Hello (ECH)

简介

本文介绍 TLS 1.3 的 Encrypted Client Hello (ECH) 扩展,它是 Encrypted Server Name Indication (ESNI) 的继任者,旨在加密 TLS 握手中的敏感信息以提升隐私保护。

本文回答

  • ECH 是什么、解决什么问题
  • ECH 的工作原理(ClientHelloInner/ClientHelloOuter 双重结构)
  • ECH 与 REALITY 的关系和区别
  • REALITY 中 ECH 的支持情况

本文在项目中的位置

本文属于背景知识层。ECH 是与 REALITY 同领域的隐私增强技术,但解决问题的方式不同。理解两者的区别对于理解 REALITY 的设计选择很重要。

适合读者

所有想理解 TLS 隐私增强技术的读者。

前置知识

TLS 1.3 握手流程,HPKE 基础概念,SNI 的作用。

文章理解难度

中等。需要理解 TLS 握手消息结构。

重点

  • ECH 如何使用 HPKE 加密 ClientHello
  • ECH 与 REALITY 在设计思路上的本质区别
  • REALITY 中的 ECH 支持

上级文档和相关文档

主要证据

Cloudflare ECH 技术博客,RFC draft-ietf-tls-esni,wolfSSL ECH 实现文档,REALITY ech.go 源码。


SNI 的隐私问题

SNI(Server Name Indication)是 TLS 握手中的一个关键字段。当一台服务器托管多个 HTTPS 网站时,客户端在 ClientHello 中以明文发送 SNI,告知服务器需要哪个网站的证书。

SNI 明文的隐私问题:

  • 网络路径上的任何观察者都可以看到用户正在访问哪个域名
  • 审查方可以基于 SNI 实施域名级别的访问控制
  • ISP 可以收集用户浏览的域名信息

ECH 的设计目标就是解决这个问题——加密 ClientHello 中的敏感字段

ECH 工作原理

ECH 是 TLS 1.3 的一项扩展(RFC draft-ietf-tls-esni),其核心思想是使用双重 ClientHello 结构:

双重 ClientHello 结构

ClientHelloOuter(明文,发送到网络)
├── 版本、随机数等普通字段
├── SNI: cover.example.com(掩护域名)
├── 密码套件、扩展等(与正常 ClientHello 相同)
└── ECH Extension
    └── ClientHelloInner(加密)
        ├── SNI: real-target.example.com(真实目标域名)
        ├── 真实的密码套件和扩展
        └── 其他敏感字段

ECH 握手流程

关键机制

  1. HPKE 加密:ECH 使用 HPKE(Hybrid Public Key Encryption)加密 ClientHelloInner。HPKE 结合了非对称加密(密钥交换)和对称加密(AES-128/256-GCM 或 ChaCha20Poly1305),一次握手即可安全传输加密内容。

  2. ECH 配置分发:客户端在连接前需要获取服务端的 ECH 公钥(ECHConfigList)。获取方式包括:

    • DNS HTTPS 记录(通过 DoH/DoT 防止 DNS 层面的篡改)
    • 前一次连接中的 retry_configs
  3. 回退机制:如果 ECH 被服务端拒绝,服务端会发送 ECHRetry 消息,其中可能包含新的 ECHConfig 供客户端重试。客户端会收到 ECHRejectionError

ECH 的安全性

ECH 保护 ClientHello 中的敏感信息不被网络观察者读取,但:

  • 客户端 IP 地址仍然暴露
  • 服务端 IP 地址仍然暴露
  • 数据包的大小和时序特征仍然可观察
  • ECH 本身不阻止主动探测

ECH vs REALITY

维度ECHREALITY
问题保护用户隐私,防止 SNI 泄露对抗网络审查,防止代理流量被检测
方法加密 ClientHello 中的敏感字段将代理流量伪装成普通 HTTPS 流量
证书使用真实 CA 签发的证书使用临时自签 Ed25519 证书(带认证)
SNI 处理加密真实 SNI,使用掩护域名直接使用目标网站的真实 SNI
部署要求需要控制服务端(配置 ECH 密钥)不需要控制目标网站(指向任何网站即可)
对审查方的可见性能看到加密的 ClientHello(知道有人在使用 ECH)看到的完全就是普通 HTTPS 流量
标准化状态IETF 草案,接近最终标准非标准协议,项目自有的实现

ECH 和 REALITY 解决的是不同层面的问题:

  • ECH 是隐私增强技术,让审查方不知道你访问了哪个网站
  • REALITY 是流量伪装技术,让审查方不知道你使用了代理

两者可以组合使用——REALITY 服务端的 TLS 实现确实包含了 ECH 支持。

REALITY 中的 ECH

源码位置:REALITY/ech.go(20,047 字节)

REALITY 的 TLS fork 实现了 ECH 草案的支持,包括:

  1. 客户端 ECH:当配置了 EncryptedClientHelloConfigList 时,客户端会尝试使用 ECH
  2. 服务端 ECH:当配置了 EncryptedClientHelloKeys 时,服务端可以处理 ECH 请求
  3. HPKE 支持REALITY/hpke/ 目录包含 HPKE 的实现(hpye.go

在 xray-core 的 TLS 传输层(xray-core/transport/internet/tls/ech.go)中,ECH 配置被映射到 TLS 连接配置:

go
// 客户端配置
tlsConfig.EncryptedClientHelloConfigList = ... // ECH Config

// 服务端配置
tlsConfig.EncryptedClientHelloKeys = ... // ECH 密钥

使用场景

  • REALITY + ECH:REALITY 负责流量伪装,ECH 额外加密 SNI——让审查方既看不到你的目标域名,也看不出你在使用代理
  • TLS + ECH:在标准的 TLS 传输层中启用 ECH,适用于不需要 REALITY 级别伪装但需要 SNI 隐私的场景

外部参考资料

资料:Good-bye ESNI, hello ECH! 类型:技术博客(Cloudflare) 链接:https://blog.cloudflare.com/encrypted-client-hello 可信度:A,Cloudflare 是 ECH 标准的主要推动者之一

资料:wolfSSL ECH 实现和文档 类型:官方文档 链接:https://www.wolfssl.com/how-and-why-to-use-ech-encrypted-client-hello 可信度:A

资料:REALITY ech.go 源码 类型:源码 链接:REALITY/ech.go 可信度:A

读者自检

读完本文后应能回答:

  • ECH 解决的核心问题
  • ClientHelloInner/ClientHelloOuter 的区别
  • HPKE 在 ECH 中的作用
  • ECH 和 REALITY 的核心区别
  • 两者如何组合使用

下一步阅读