2013-03-08 40 views
0

我的问题是 - 如何确定输出密文的长度?分组密码输出长度拼图

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

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

谢谢!

+0

更适合http://crypto.stackexchange.com/ – jbtule 2013-03-08 13:27:47

回答

1

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

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

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

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

+1

否,#2不正确。输出长度将与下一个块边界对齐。只需将块大小添加到明文大小(通常可以快速计算缓冲区大小)就会导致数字太高。 – 2013-03-08 12:17:15

+0

@owlstead你是完全正确的,我纠正了我的答案。 – Robert 2013-03-08 12:36:05

2

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

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

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

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

大号密文 =(L 明文/L )*(L + 1)

其中L 明文/L 是圆形(像往常一样,在大多数编程语言中进行整数计算)。

现在让我们假设AES,它总是具有16个字节的块大小:

0 bytes -> 16 bytes 
    1 byte -> 16 bytes 
    2 bytes -> 16 bytes 
... 
15 bytes -> 16 bytes 
16 bytes -> 32 bytes 
17 bytes -> 32 bytes 
... 

注意,有相当一些实现使用非标准化的填充。一个例子是PHP中的mcrypt库(你可以使用mcrypt作为密码学中任何不良练习的基础)。这使用零填充,因此只需填充00值字节,直到明文块对齐。在这种情况下所得到的大小可以这样计算:

大号密文 =(L 明文/L - 1)*(L + 1)

显然运行在任何不期望非标准化零填充的实现中使用它,或者当明文可能以一个或多个00值字节结尾时,会导致麻烦。最后说明:一些语言(例如,Java Cipher)具有从加密实现中检索块大小和甚至得到的密文的方法。在你开始实施自己的事情之前,它绝不会伤害到检查API。

在编写本文时,维基百科对padding modes有一个很好的解释。