AES / CBC和AES / ECBencryption后的数据大小

我想知道AESencryption后的数据大小,这样我就可以避免为了知道大小而caching我的后AES数据(在磁盘或内存上)。

我使用128位AES和javax.crypto.Cipherjavax.crypto.CipherInputStream进行encryption。

用各种input大小进行的一些testing表明,按照下面计算的后encryption大小是正确的:

 long size = input_Size_In_Bytes; long post_AES_Size = size + (16 - (size % 16)); 

但我不确定上述公式是否适用于所有可能的input大小。

是否有一种方法可以在应用AESencryption之后计算数据的大小 – 事先不必缓冲encryption数据(在磁盘或内存上)以了解其后encryption大小?

AES的固定块大小为16个字节,与密钥大小无关。 假设你使用PKCS 5/7填充,使用这个公式,

  cipherLen = (clearLen/16 + 1) * 16; 

请注意,如果明文是块大小的倍数,则需要填充整个新块。 说你明文是16字节。 密文将占用32个字节。

您可能需要使用密文来存储IV(初始向量)。 在这种情况下,您需要为IV增加16个字节。

AES作为分组密码不会改变大小。 input大小始终是输出大小。

但是AES是分组密码,要求input是块大小(16字节)的倍数。 为此,像stream行的PKCS5一样使用填充scheme 。 所以答案是你的encryption数据的大小取决于使用的填充scheme。 但是同时, 所有已知的填充scheme都会向下取整到下一个模块16的大小(大小为AES的块大小为16字节)。

这取决于您使用AES的模式。 对于大多数面向块的模式(如ECB和CBC),您所拥有的是准确的。 OTOH,在CFB模式下(举一个例子),你基本上只是使用AES来产生一个字节stream,这个字节与input的字节异或。 在这种情况下,输出的大小可以保持为input大小,而不是像上面给出的那样四舍五入到下一个块大小。

一般来说,对于一个分组密码encryption:

CipherText = PlainText + Block – (PlainText MOD Block)

密文大小被计算为扩展到下一个块的明文的大小。 如果使用填充,并且明文的大小是块大小的精确倍数,则会添加一个包含填充信息的额外块。

AES使用16字节的块大小,从而产生:

CipherText = PlainText + 16 – (PlainText MOD 16)

来源: http : //www.obviex.com/articles/CiphertextSize.pdf

注意:

  1. CipherText和PlainText相应地表示密文的大小和纯文本的大小。

AES密码总是在16字节(128位)块上工作。 如果input字节数不是16的精确倍数,则填充。 这就是为什么16在你的计算中似乎是“魔术数字”。 你有什么应该适用于所有input大小。

AES以128位(16字节)块的forms工作,并将明文块转换为相同长度的密文块。 它填充最后一个块,如果它比16个字节短,所以你的公式看起来是正确的。

有一些方法可以存储encryption信息,只要数据大小至less等于块大小,就可以避免使用任何填充。 一个小问题是,如果允许数据大小小于块大小,并且必须能够重构数据的精确大小,即使对于小块,输出也必须至less比input,[i]不pipe数据大小。

要理解这个问题,要知道有256 ^ N个可能的文件长度是N字节,可能的文件长度不超过N个字节的数量是256 ^ N加上不超过N个可能的文件数量-1字节长(有一个可能的文件是零字节长,257个可能的文件长度不超过一个字节)。

如果块大小为16字节,则将会有256 ^ 16 + 256 ^ 14 + 256 ^ 13等可能的input文件长度不超过16字节,但是只有不多于16个可能的输出文件不超过16字节长(因为输出文件不能less于16字节)。 所以至less有一些可能的16字节input文件必须增长。 假设他们将变成17个字节。 有256个可能的17个字节的输出文件; 如果其中任何一个用于处理16个字节或更less的input,则将不能处理所有可能的17个字节的input文件。 无论input多大,一些或更大的文件都必须增长。