摘要

  • TLS 最初给出 16 KiB 的明文记录上限,后来允许客户端挑选一个更小、双向共用的分片值;这种对称性掩盖了接收完整受保护记录才常常是更重的内存义务。
  • RFC 8449 把大小改成按方向生效的接收声明:每一端说出自己能接收多少,对端据此组装记录;该声明约束本地原子处理,不是对路径、带宽或应用消息大小的判断。

能发出去,不等于能接得住

设想一枚带硬件加密单元的传感器。发送时,它可以一边读入明文,一边生成并输出密文,未必需要把完整结果长期留在内存里。接收时情况不同:在确认整条记录通过认证之前,它不能把尚未证实的明文交给应用。否则,攻击者只要伪造一个前缀,就可能让应用先采取行动,再等校验失败收场。

因此,记录大小并非无害的格式参数。发送者决定一次把多少应用数据或握手材料装进一个受保护单元,接收者承担把这个单元完整接收并认证的内存成本。双方都叫 TLS 端点,不代表它们拥有相同硬件;能够逐步产生大记录,也不能证明能够在反方向容纳同样大的记录。

RFC 8449 的关键不只是把数值调小,而是改变了谁有权给出这个数值。

16 KiB 是协议天花板,不是内存保证

TLS 1.2 把上层数据装入不超过 2^14 字节的 TLSPlaintext。记录层可以把一条上层消息拆进多条记录,也可以把多条同类型消息合并。因此,TLS 记录边界既不是应用消息边界,也不是 TCP 段或 IP 包边界。

对通用计算机而言,较大的记录可以摊薄首部和密码运算开销。对内存紧张的设备而言,它却形成最坏情况下的接收义务;压缩和保护还可能让线路上的对象更大。如果没有额外约定,合规接收方就必须为协议允许的最大记录做好准备,即使多数发送方平时从不填满它。

2006 年的 TLS 扩展规范以及后来的 RFC 6066 给出了 max_fragment_length。客户端只能从 512、1024、2048、4096 字节中选择一个值。服务器若接受,就必须原样回显;随后双方立即按同一个上限拆分应用数据和握手消息,这一选择还覆盖当时定义的会话恢复。

这套机制确有价值。RFC 7925 的物联网 TLS/DTLS 配置把它视为降低客户端入站缓冲需求的办法:设备不再需要为普通 TLS/DTLS 可接受的 16 KiB 记录预留空间。一个原本藏在实现里的限制,终于进入了协议协商。

旧扩展把两台机器压成一个数

问题出在协商形状。旧扩展最大的可表达值只有 4096 字节,远小于普通的 16384 字节。一个完全能接收大记录的客户端,只要提出扩展,就可能无谓地降低反向吞吐;更多小记录意味着更多首部、保护开销和处理次数。

更深的缺陷是提案权与对称性。服务器只能接受客户端选定的值,不能提出更低的自身上限。客户端若受限,也会把同一个小数值施加到自己发送和接收的两个方向。然而,记录限制通常是接收方限制:一端可能能逐步加密并发送大记录,却必须为入站记录保留完整认证缓冲。

一个“公平”的共同值,实际上让发起方独占提案,并假设两台不同设备具有同一种容量。

新扩展把数字指向声明者自己

record_size_limit 改变了语义。它表示:声明这一数值的端点,愿意接收的受保护记录明文最大有多大。对端向它发送记录时不得超过该值;声明者向反方向发送时,可以使用更大的记录,只要遵守另一端的声明以及 TLS 版本自身的总上限。

同一连接由此可以有两个不同数值。小设备能要求云端把入站记录切小,同时向具备大缓冲的云端发送更大记录。受限服务器也终于可以表达自身需求,即使客户端完全不受限。RFC 8449 甚至建议能力充足的端点也携带扩展,因为这样另一端才有机会回报自己的约束,并知道它会被遵守。

这是一种范围精确的本地权力。端点不需要向对方申请少用内存;它本来就控制自己的内存。声明只告诉对方,怎样制作与这个事实相容的受保护记录。如果 TLS 对端超过已声明上限,接收方必须以致命 record_overflow 终止连接;DTLS 接收方也可选择丢弃超限记录。

数值不得低于 64,但 64 只是协议下限,不是性能建议。RFC 8449 同时提醒:记录过小会增加双方工作量、降低吞吐,并扩大拒绝服务暴露面。

计算的是受保护明文,不是线上所有字节

不同 TLS 版本的计数边界不同。TLS 1.2 及更早版本把进入压缩和加密的材料计入上限,而加密算法增加的填充不计入。TLS 1.3 则计算完整的 TLSInnerPlaintext,包括内容、内部内容类型字节和 TLS 1.3 记录填充。

TLS 1.3 允许用填充模糊流量长度,但填充不能绕过接收方容量。缩小上限后,内容类型和填充也要占用同一预算。隐私策略与应用内容共同消耗入站记录空间。

未受保护的握手记录不受该扩展约束。会话恢复或旧式重新协商还会重新确定上限,记录遵循产生其保护密钥的那次握手。上一次会话的数值不是身份或票据的永久属性。

这不是路径测量

记录上限和路径 MTU 都可能促使发送方产生更小单元,却回答不同问题。RFC 8449 明确区分:记录上限来自端点处理能力,在握手时固定;PMTU 来自网络路径,约束包的承载,并可能在连接期间变化。多条小 DTLS 记录仍可装进同一个 UDP 数据报。

扩展也不限制 HTTP 响应、证书链或其他应用消息,这些对象可以跨越多条记录。它不承诺带宽、计算速度、代码空间、电池寿命,也不解决一切内存问题。它只缩小一项义务:接收方作为完整受保护单元处理的明文规模。

IANA 目前把编号 28 的 record_size_limit 标为 Recommended,把编号 1 的 max_fragment_length 标为不推荐。这是标准登记状态,不是产品支持率或部署正确性的证明。

这段历史真正修正的是协议对称性的想象。TLS 不必让两端变得一样;它只需让每一端声明那个只有自己最清楚的边界,并要求对端在成本落向该端的方向上服从它。

来源与证据边界

本文依据 RFC 4366、RFC 5246、RFC 6066、RFC 7925、RFC 8446、RFC 8449 与 IANA TLS ExtensionType 登记表。这些材料证明协议设计与登记状态,不提供当前部署比例、具体设备内存配置或某类负载的最佳记录大小。