零填充
定义
零填充是一种把短于分组长度的数据补齐到分组长度整数倍的方法,具体做法是在数据末尾追加若干个值为零的字节[1]。在 分组密码 的多种工作模式中,待加密数据的长度必须是分组长度(例如 AES 的 16 字节、DES 的 8 字节)的整数倍,不够的部分就需要填充[4]。零填充在部分编程库中被称为 Zeros 模式或 Null 填充,与 PKCS7、ANSIX923、ISO10126 等填充方案并列[5]。
零填充属于确定性填充,即同样的输入总会得到同样的输出,填充本身不引入随机性[6]。多数纯文本消息的字节数不会恰好填满分组,因此需要追加填充串;零填充就是让这一段填充串全部由零值字节构成[1]。
原理
设分组长度为 $B$ 字节、数据长度为 $L$ 字节。零填充先计算余数 $m = L \bmod B$,当 $m$ 不为零时追加 $B - m$ 个零字节,使填充后的长度成为 $B$ 的整数倍[6]。例如分组长度为 8 字节时,3 字节的数据会被补齐为 $0a\ 0b\ 0c\ 00\ 00\ 00\ 00\ 00$[7]。
零填充存在两种实现变体,差异在于当数据长度本身已是分组长度整数倍时的处理:一种不追加任何字节,另一种追加一个完整的零字节分组[8]。两个变体在解密端的处理也不同,有的实现会在解密时剥除末尾的零字节,有的则保留填充结果[8]。
flowchart LR
A[明文 L 字节] --> B{L mod B == 0 ?}
B -- 否 --> C[追加 B - (L mod B) 个 0x00]
B -- 是 --> D[不追加或追加一个零分组]
C --> E[长度为 B 整数倍的数据]
D --> E
E --> F[送入分组密码加密]
应用
零填充用于分组密码的 ECB 与 CBC 等需要固定长度输入的模式,当明文长度与分组长度不匹配时补齐最后一个分组[9]。部分语言和库提供直接的零填充接口,例如 Go 生态中的若干工具库提供 DES 在 ECB 或 CBC 模式下配合零填充的便捷加密函数[10],Haskell 的 cryptonite 库则以 ZERO 参数表示按指定分组长度进行零填充[6]。
除数据填充外,零填充还有另一种用法:在消息前面加上一段固定的零字节前缀,解密时校验该前缀是否完整。这种变换被用于把基于 CTR 模式 的加密方案(例如 GCM 与 ChaCha20/Poly1305)改造为具备密钥承诺性质的方案,曾有协议草案推荐用它来支持信封加密[11]。
零填充也出现在密钥派生场景中,可把较短的记忆型口令按字节补零,扩展到 AES-128、AES-192 或 AES-256 所需的 16、24 或 32 字节密钥长度[12]。
局限
零填充最突出的问题是不可逆:填充字节不携带长度信息,解密端无从判断数据末尾的 0x00 是原文内容还是补充的填充[3]。如果原始数据本身以若干零字节结尾,剥除填充时就会把这些字节一并删除,导致还原结果与原文不一致[13]。
这一缺陷使零填充不适合对任意二进制数据做通用加密,一般只用于可确定不以零字节结尾的数据,例如 ASCII 文本[13][14]。相比之下,PKCS7 填充的每个填充字节都等于填充字节数,因而能够恢复被填充的长度,其定义在 RFC 2315 中唯一确定,不存在多个互不兼容的变体[8]。
零填充的多种实现变体还会带来互操作问题:不同库对数据已对齐时是否追加完整分组、解密时是否剥除填充的处理并不统一,跨实现交换数据时容易出现结果差异[8]。此外,把短口令直接补零扩展为密钥的做法缺少昂贵的密钥派生过程,攻击者可对候选口令快速重复该过程并检验密文,从而降低破解成本[12]。
参见
参考资料
- PaddingMode 列舉 (System.Security.Cryptography) [引用日期2026-10-14]
- c#中对称加密的填充模式有哪些 [引用日期2026-10-14]
- Can AES128 CBC uses 0-padding? [引用日期2026-10-14]
- understanding-padding-in-symmetric-key-cryptography [引用日期2026-10-14]
- PaddingMode [引用日期2026-10-14]
- | [引用日期2026-10-14]
- Function types [引用日期2026-10-14]
- Revision ecf45be6-92cc-4a82-b7b3-64c08e8336f5 [引用日期2026-10-14]
- 问AES-128 CBC加密:密文大小似乎太大了EN [引用日期2026-10-14]
- codec [引用日期2026-10-14]
- and recast Equation 9 as a 4- sum problem [引用日期2026-10-14]
- 问AES密钥零填充的主要问题是什么?EN [引用日期2026-10-14]
- zero [引用日期2026-10-14]
- Revision [引用日期2026-10-14]