Block Cipher输出长度拼图

时间:2013-03-08 10:14:15

标签: cryptography block encryption

我的问题是 - 如何确定输出密文的长度?

我隐约知道输出长度必须是正在使用的密码的块大小的倍数。但这是否意味着:

  1. 如果输入数据的长度是密码块大小的倍数,那么输出长度将与输入长度相同?
  2. 如果输入数据的长度不是密码块大小的倍数,那么输出长度将是输入长度+一个块大小?
  3. 谢谢!

2 个答案:

答案 0 :(得分:2)

罗伯特关于密文大小是正确的,取决于密码模式和填充,以及可能的块模式。

如果在流模式下使用密码(例如CTR),则密文大小与明文大小相同。如果您使用经过身份验证的模式(如GCM),则必须至少使用身份验证标记来增加此模式。您也可以使用CBC模式将密文窃取到(CTS)以消除填充开销,但这只适用于两个或更多块。

现在让我们假设CCS模式的PKCS#5/7兼容填充,这是目前最常用的模式。在这种情况下,您的明文至少填充一个填充字节(否则,无法填充无法区分例如用单个01值填充字节填充的明文和明文 - 可以按块大小分割 - 以{{结尾1}}有价值的字节)。这意味着如果明文已经块对齐,则会添加整个块。

当然,如果明文不是块对齐的,那么PKCS#7填充只需要填充最后一个块。因此,在这种情况下,添加1到01个字节。所以计算结果如下:

L ciphertext =(L 明文 / L block )*(L block + 1)

其中L 明文 / L 向下舍入(与大多数编程语言中的整数计算一样)。

现在假设AES,其块大小始终为16字节:

block size

请注意,有一些实现使用非标准化填充。一个例子是PHP中的mcrypt库(您可以使用mcrypt作为加密中任何不良做法的基础)。这使用零填充,因此它只是填充 0 bytes -> 16 bytes 1 byte -> 16 bytes 2 bytes -> 16 bytes ... 15 bytes -> 16 bytes 16 bytes -> 32 bytes 17 bytes -> 32 bytes ... 值的字节,直到明文被块对齐。在这种情况下,结果大小可以这样计算:

L ciphertext =(L 明文 / L block - 1)*(L block + 1)

当你在任何不期望非标准化零填充的实现中使用它时,或明文可能以一个或多个00值的字节结束时,显然会遇到麻烦。

最后注意事项:某些语言(例如Java 00)具有检索块大小甚至是加密实现中产生的密文的方法。在开始自己实现之前检查API永远不会受到伤害。

维基百科在撰写本文时对padding modes有很好的解释。

答案 1 :(得分:1)

输出密文的长度取决于块长度,密码模式以及是否使用填充。

像CTS这样的密码模式可以创建一个等于输入的密码输出长度,即使使用分组密码也是如此。

关于1: 如果输入数据的长度是密码块大小的倍数并且使用了填充,则输出长度将比一个块大一个,因为您需要至少一个字节来指定填充长度。

关于2:输出长度必须是块长度的倍数,因此它是输入长度+(输入长度​​ mod 块长度)

相关问题