# ESNI是什么？定义、例子与常见误区

> ESNI 是一个已被放弃的 TLS 1.3 草案，用发布在 DNS 中的公钥只加密 SNI 字段，现已被 ECH 取代。

Source: https://ssl.sh/zh/glossary/esni/
Last updated: 2026-11-10

ESNI 是 IETF 早期的草案设计：服务器把公钥发布在 `_esni.<域名>` 的 DNS TXT 记录里，客户端用它加密 TLS 1.3 ClientHello 中的 [SNI](https://ssl.sh/zh/glossary/sni/) 扩展。Cloudflare 和 Firefox 曾在 2018 年前后做过试验，但它从未成为 RFC。TLS 工作组随后把它重新设计为 [ECH](https://ssl.sh/zh/glossary/ech/)，加密整个 ClientHello，并于 2026 年 3 月发布为 RFC 9849。

## 为什么重要
如今 ESNI 的意义主要在于理解历史、避免混淆。只加密 SNI 被证明覆盖面太窄：ClientHello 里的其他扩展（例如 ALPN 列表）仍可能泄露目标信息；客户端拿到过期密钥时，也缺少可靠的恢复手段。ECH 用内外两层 ClientHello 和重试机制解决了这些问题。Firefox 已移除 ESNI、改为支持 ECH，服务器端也不再提供 ESNI。如果某篇教程或某个软件还在讲如何开启 ESNI，说明内容已经过时。

## 例子
两种方案发布密钥的方式不同：

```text
; ESNI（已废弃的草案）：密钥放在 TXT 记录
_esni.example.com.  IN TXT    "<base64 ESNIKeys>"

; ECH（RFC 9849）：配置放在 HTTPS 记录
example.com.        IN HTTPS  1 . alpn="h2" ech="<base64 ECHConfigList>"
```

## 常见误区
- **ESNI 和 ECH 只是叫法不同。** ESNI 只加密一个扩展；ECH 加密完整的内层 ClientHello，而且是唯一完成标准化的方案。
- **在浏览器里打开 ESNI 仍能增强隐私。** 主流浏览器已不再实现 ESNI，服务器也不接受，应当关注的是 ECH。
- **之所以需要 ESNI，是因为 TLS 1.3 明文发送证书。** [TLS 1.3](https://ssl.sh/zh/glossary/tls-1-3/) 已经加密了服务器证书，剩下的明文域名正是 SNI 本身，所以单靠 TLS 1.3 无法隐藏访问目标。

## 相关术语

- [ECH](https://ssl.sh/zh/glossary/ech/): ECH 是 TLS 1.3 的扩展，用发布在 DNS 中的公钥加密 ClientHello 的敏感部分（包括 SNI），链路上只能看到前端服务器的公共名称。
- [SNI](https://ssl.sh/zh/glossary/sni/): SNI 是 TLS 的一个扩展，客户端在 ClientHello 中写明要访问的域名，使同一个 IP 能为多个 HTTPS 站点分别返回各自的证书。
- [TLS 1.3](https://ssl.sh/zh/glossary/tls-1-3/): TLS 1.3 是当前最新的传输层安全协议版本（2018 年的 RFC 8446，现行规范为 RFC 9846），完整握手只需一个往返，且只保留 AEAD 加密算法。
- [TLS 握手](https://ssl.sh/zh/glossary/tls-handshake/): TLS 握手是 TLS 连接开始时的一组消息交换，客户端与服务器在其中协商协议版本和密码套件、验证服务器身份并派生会话密钥。
- [DNSSEC](https://ssl.sh/zh/glossary/dnssec/): DNSSEC 是一组 DNS 扩展，让解析器能沿着从根区开始的签名链，验证 DNS 应答确实来自权威方且未被篡改。
