AES 256 GCM 是否对其密文施加了任何限制字节序列?

AES 256 GCM 是否对其密文施加了任何限制字节序列?

具体来说,我想询问的是,密文是否可以包含诸如这样的字节序列170303,这是一种可能的 TLS 记录头。

通常,解析 TCP 字节流的应用程序会通过解析标头并从标头开始后的第 4 个和第 5 个字节中提取八位字节的长度来界定 TLS 记录。然后,我假设它会跳过并尝试读取由先前解析的标头计算出的偏移量的下一个记录。

我的问题是,TLS 1.3 的 AES 256 GCM 实现是否对密码输出施加了任何限制?RFC 没有提及它。是否可以有一个以 header 开头170303xxxx,但同时也包含 的TLS 记录170303作为其密文的一部分?

答案1

除了一些特殊的(非常罕见的)“格式保留”模式外,所有现代加密算法(包括 AES-GCM)都可以处理明文中的任何字节序列并生成任何字节序列作为密文。(事实上算法几乎可以处理任何少量序列,但是实现在面向字节的计算机上,大多数只处理字节,特别是因为它们通常是用 C 编写的,而 C 对子字节数据的支持依赖于实现。AES-GCM 是一个例外;它由 AES-CTR 和 GMAC 组成,两者都可以处理任何位,但 NIST 仍然指定 GCM 只处理 8 位字节。可能是因为他们过去曾遇到过加密实现问题,据称经过了一致性测试,但在极端情况下仍然会失败,而且现在几乎没有人需要甚至想要非字节加密。)

当数据受到限制时(例如通过非 MIME 电子邮件发送密文,或将其存储在某些不支持二进制(又称“blob”数据)的数据库中),通常会编码以满足这些约束的形式的密文,例如十六进制、base64、URL 安全的 base64、base32、base58、base95 等。但是 SSL/TLS(所有版本)不需要这样做;在记录级别,它允许正文中的任何字节序列,是的,因此每个记录仅由记录头中指定的长度分隔,而从不由其内容分隔。(一些记录(例如握手子协议中的记录)对其内容确实有限制,但如果加密,这些限制适用于加密前或解密后的明文,而不是密文。)

答案2

任何能够加密任意二进制数据的分组密码都必须能够在其输出中生成所有字节序列,或者其输出必须至少在某些输入上大于其输入。但 AES-GCM 生成相同大小的输出并接受二进制输入。

如果有任何限制,那么输出的每个字节的熵会比完全随机的输入要少。也就是说,可能的输出值会少于 2^n 个,其中 n 是输出长度(以位为单位)。这意味着它无法以该长度对 2^n 个可能的输入流中的每一个进行唯一编码。

(这个原理在一般情况下都是正确的,不仅适用于密码,也是为什么不能无损压缩任意随机数据的原因。通常称为鸽巢原理。 https://en.wikipedia.org/wiki/Pigeonhole_principle

相关内容