ESP 的填充长度只计紧挨在它前面的填充字节,取值 0 到 255。它不含流量保密填充,也不含填充长度和下一头这两个字节。选了机密性时,显式尾部在密文里。SPI 和序列号仍以明文发出。规范是 2005 年 12 月的 RFC 4303。
尾部从填充长度往回数
一个可独立引用的定义句:填充长度表示紧挨在它前面的填充字段里有多少个填充字节。合法值是 0 到 255。0 表示没有填充字节。这不包括任何流量保密填充。填充长度字段本身是强制的(RFC 4303 第 2.5 节)。
包以两个 4 字节字段开头:SPI 和序列号。其后是载荷数据。再后面才是填充、填充长度和下一头。可选的完整性校验值在最后。第 2 节写明,发出去的 ESP 尾部由填充、填充长度和下一头组成。另有不发出的隐式尾部数据,只参加完整性计算。
| 字段 | 表 1 的字节数 | 分开的算法、且选了加密时 | 表 1 的发出形式 |
|---|---|---|---|
| SPI | 4 | 加密不盖住 | 明文 |
| 序列号低 32 位 | 4 | 加密不盖住 | 明文 |
| 填充 | 0 到 255 | 在密文里 | 已选择加密时才是密文 |
| 填充长度 | 1 | 在密文里 | 同上 |
| 下一头 | 1 | 在密文里 | 同上 |
| 序列号高 32 位 | 4,仅在使用 ESN 时 | 参加完整性,不加密 | 不发出 |
表 1 的原注写:cipher 表示已经选择了加密时才是密文。没有选择加密时,本文不把填充长度和下一头写成密文。表 2 是组合模式,这两字节仍标成在加密覆盖范围内。组合模式可以不在包尾单列完整性校验值。高 32 位序列号发不发出,表 2 写由算法决定,对 ESP 来说结果不可见。各算法 RFC 本文没有重读,因此不给 GCM 或 CBC 的校验值编一个固定字节数。
关键词按 RFC 2119。下文的「必须」对应原文的大写 MUST。第 2.4 节有一处小写 must,单独标明。
紧挨在 ESP 前面的那个头,其协议字段(IPv4)或下一头(IPv6 或扩展头)必须取值 50。这个 50 不是尾部的下一头。尾部的下一头标识载荷数据里是什么,例如 4 表示 IPv4,41 表示 IPv6,6 表示 TCP。传输模式和隧道模式把这些值放在哪一层,见 传输模式与隧道模式。
0 表示没有填充字节
一个可独立引用的定义句:发送方可以添加 0 到 255 字节的填充。填充字段出现与否是可选的,但所有实现都必须能生成并处理填充。需要填充而加密算法又没有规定填充内容时,必须使用默认处理:第一个填充字节是 1,随后单调增加,即 1、2、3……使用这一方案时,接收方应当检查填充字段(RFC 4303 第 2.4 节)。
「应当」对应这里的大写 SHOULD。默认序列的理由原文写了三条,其中一条是:在没有其他完整性措施时,若接收方检查这些值,对某些剪切粘贴能提供有限防护。本文不写那种剪切怎样构造。算法若对填充字节的取值另有约束,必须由说明该算法如何与 ESP 一起使用的 RFC 规定。那种 RFC 本文没有重读。
第 2.4 节列出填充的两个直接原因。一是加密算法要求明文是若干字节的倍数,明文包括载荷数据、填充、填充长度和下一头。二是不论算法要求如何,使得到的密文停在 4 字节边界上。具体写法是:填充长度和下一头必须在一个 4 字节字内右对齐,图就是这样画的,以便完整性校验值若存在则对齐到 4 字节边界。这里的「必须」在原文是小写 must。本文不升成大写。超过算法或对齐所需的填充,原文写不应当拿来做流量保密,应改用第 2.7 节。这里的「不应当」和「应」是对原文 should not 与 should 的转述。
对齐所用的填充,计算范围含初始化向量、填充长度和下一头。凑块长所用的填充,计算范围不含初始化向量,但含尾部字段。两句的「含不含初始化向量」并不相同。本文不把它们收成一个公式。
流量保密填充是另一段,放在载荷数据之后、上述填充之前。第 2.7 节写,普通填充最多 255 字节,一般不够用来隐藏流量特征。这种额外填充只有在载荷数据自己标明 IP 数据报长度时才能加。隧道模式总是满足。传输模式则取决于下一层协议有没有明确长度,原文举的例子是 IP、UDP 和 ICMP。接收方能丢掉它,是因为真实长度已知。原文接着写:ESP 尾部字段靠从 ESP 包的末尾往回数来定位。长度字段不得改成把这份填充算进去。本文没有测量某一实现加不加它。
图 2 的脚注把流量保密填充指向第 2.4 节。已验证勘误 4798 把这一处改成第 2.7 节。第 2.6 节引入哑包时同样指向了第 2.4 节,已验证勘误 4799 改成第 2.7 节。本文按改后的节号引用,不按脚注里印错的 2.4。
下一头取值 59 表示没有下一个头,用来标记哑包。发送方必须能够生成这种包,接收方必须准备丢掉它们,并且不把它当成差错。其余字段,包括 SPI、序列号、填充、填充长度、下一头和完整性校验值,在哑包里必须仍然存在。载荷里除了这个下一头以外的明文不必格式正确。本地管理开关是 SHOULD。第 2.6 节的讨论写,哑包可以按随机间隔插入。本文不写间隔怎么取,也不提供生成步骤。59 与传输模式的关系,前引那一篇已经写过。
SPI 和序列号不在这段尾部里
SPI 是任意的 32 位值,用来让接收方找出安全关联,字段强制出现。0 留给本地、实现专用,不得在线上发送。1 到 255 由 IANA 保留。线上怎样用「不是 0」把 ESP 和 IKE 分开,见 非 ESP 标记。本文不重写那四个 0。
序列号是无符号 32 位,每个发出的包加 1。字段强制出现,即使接收方没有对这条安全关联打开重放保护,发送方也必须发送它。计数器在安全关联建立时置 0。使用这条安全关联发出的第一个包,序列号是 1。打开重放保护时(这是默认),原文先用小写 must 写:传送的序列号不得回绕。紧接着的大写 MUST 是:在这条安全关联上发出第 2^32 个包之前,发送方和接收方的计数器都必须重置,办法是建立新的安全关联,从而换用新密钥。窗口怎样滑动,见 重放保护。本文不重写窗口宽度。
扩展序列号把计数器做成 64 位。线上的明文 ESP 头里只发低 32 位。高 32 位由收发双方各自保持,并在选择了完整性时进入完整性校验值的计算。使用单独的完整性算法时,高位放进隐式尾部,不发出。使用组合模式时,发不发出由算法决定。IKEv2 里这项协商是隐含的:除非明确协商 32 位序列号,默认是扩展序列号。这是第 2.2.1 节的句子。协商载荷怎样把这个选择写进通用载荷头,不在本文展开。
完整性若被选择,计算范围包括 SPI、序列号、载荷数据和 ESP 尾部,含显式和隐式。机密性若被选择,密文由载荷数据(除去可能包含的密码同步数据)和显式尾部组成。因此选了加密时,填充长度和下一头在密文里,SPI 和序列号不在。初始化向量若放在载荷字段里,通常本身不被加密。图 1 的星号就是这句。已验证勘误 1654 改的是第 3.4.4.1 节的实现注记:隐式填充按完整性算法的规定来补,不一律写成补零。本文不引用被替换的那句。
下一层协议头的开头相对 ESP 头开头的对齐,第 2.3 节用大写 MUST:IPv4 是 4 字节的倍数,IPv6 是 8 字节的倍数。这是头的位置,不是填充长度字段的单位。认证头用另一套载荷长度,见 认证头。那一篇的「字数减 2」不要拿来读 ESP 这个 0 到 255。
已验证勘误 6559 认为第 3.1.1 节传输模式的图应把 orig IP hdr 改成 updated IP hdr,因为协议、总长度和 IPv4 头校验和要改。勘误说明里引用了 RFC 3948 的一句。本文没有重读 RFC 3948,不把那一句写成 RFC 4303 正文里已经印出的句子。头校验和盖住哪些字节,见 IPv4 头校验和。
现象对照
| 现象 | 更可能先看什么 |
|---|---|
| 填充长度把下一头也计为 1 | 与第 2.5 节不符。它只计紧前面的填充字节 |
| 填充长度大于 255 | 不在第 2.5 节的合法值里。更长的掩盖要用第 2.7 节的流量保密填充,而且那个长度不写进填充长度 |
| 填充长度是 0,后面却没有下一头 | 填充字节可以没有。填充长度和下一头仍然必须出现 |
| 从 IP 头的协议字段去读内部是 TCP 还是 IPv6 | 紧前面的头应是 50。内部类型在尾部的下一头 |
| SPI 或序列号随填充长度一起被当成密文 | 这两字段在表里是明文。密文在选了机密性时才盖住显式尾部 |
| 高 32 位序列号出现在线上的 ESP 头里 | 单独的完整性算法不发送它。组合模式则由算法决定 |
核对清单
- 填充长度是 0 到 255:只计紧前面的填充。0 表示没有这些字节。字段本身仍在。不含流量保密填充;
- 下一头是紧跟着的 1 字节:4、41、6 是例子。59 是哑包。外层协议字段是 50,不是这个下一头;
- 尾部靠从包尾往回数:第 2.7 节用来丢掉流量保密填充。图 2 脚注和第 2.6 节的节号,已验证勘误 4798、4799 改到第 2.7 节;
- 选了加密,显式尾部才在密文里:SPI 和序列号各 4 字节,明文发出。SPI 不得为 0。高 32 位默认不在单独完整性算法的线上头里;
- 默认填充内容是 1、2、3…… 只在算法没有另外规定时必须使用。算法 RFC 没有重读。隐式填充不按已替换的「补零」那句引用。
2026 年 10 月 24 日的元数据把 RFC 4303 标成 Proposed Standard,没有列出更新者,也没有把它标成已被取代。已验证勘误共 5 条:133 改第 3.3.4 节的 IPv6 分片注记,1654、4798、4799、6559 如上。Held for Document Update 有 3 条,本文没有读完,因此不引用其中关于「仅加密是否够安全」的改写建议。