是否可以确保使用AES128 / CBC / PKCS5Padding加密的字符串永远不会有尾随等于字符

时间:2018-01-19 02:34:54

标签: encryption cryptography language-agnostic

是否有确定的方法可确保使用AES128 / CBC / PKCS5Padding创建的任何加密/编码字符串从不具有' ='填充结尾的字符?

鉴于加密工具是一个黑盒子:

String originalValue = "this is a test";
String encryptedValue = TheCryptoUtil.encrypt(original);

encryptedValue通常如下所示:

R2gDfGwGvkqZWHH4UF81rg==

有没有办法改变" originalValue"例如通过用空格填充输入,这样,无论TheCryptoUtil使用哪个键,输出都不会有任何" ="最后?

2 个答案:

答案 0 :(得分:1)

是的,有可能。我不知道你为什么要这样做,但这是可能的。要记住的事情:

  • 带有PKCS5Padding的AES-128的输出将始终是16的倍数。即len(ciphertext) % 16 == 0
  • 您在密文末尾看到的等号与AES无关。它们实际上是base64填充。
  • Base64接受3个字节的块作为输入,并将它们转换为4个字符的块,其中这些输出4个字符是64个定义字符中的任何一个。

这意味着输出的字节数决定了输出的base64是否具有填充。例如,如果你加密消息The quick brown fox jumps over the lazy dog.,我会说它很可能(取决于你的“黑盒子加密”)结果不会有任何base64填充。

因此,base64始终生成一个长度可被4整除的编码字符串这一事实意味着我们可以轻松确定原始长度是否有填充。实际上,base64填充只是帮助解决串联问题的规范的一部分。

我希望你能从这里弄清楚其余部分!

答案 1 :(得分:0)

卢克的回答是正确的,说AES与填充无关,但它缺少下面的一些信息。

如果输入不能被3分割,则基数64通常会产生填充。填充只是为了确保输出只包含基本64字母表中的4个字符的块。 Base 64编码64个值或每个字符6位。 3个字节是24位,可以被6分割,只需要4个字符。

天真的做法是调整AES输出,使其可以被3分割。但是,在AES / CBC / PKCS5Padding的输入上最多可能需要34个额外的填充字节,这是最好的愚蠢。 / p>

并非所有base 64方案实际上都使用填充,因此完成此操作的最简单方法就是选择一个根本不执行填充的base 64方案。例如,Java有一个withoutPadding()配置方法。

如果base 64编码器无法处理,则可以在生成后简单地删除填充。在解码之前,您可以添加一个或两个'='个字符,直到您计算可被4分割的基本64个字符(不包括空白,请参阅注释)的数量。

请注意,base 64通常也会在字母表中使用/+(如果使用大写/小写字符和数字,则只有2 * 26 + 10 = 62个字符)。你可以查找一个URL安全的base 64编码 - 名为 base64url - 如果这就是你所追求的。

顺便说一句,Base64 for MIME也可以使用空格和行尾字符。