在AES加密中使用带有NoPadding的CBC是否正确?

时间:2013-10-15 15:41:16

标签: encryption aes cryptojs

我目前正在使用mcrypt.java来加密和解密服务器端的数据和客户端的cryptojs,但是我遇到了一些问题,因为当我加密任何字符串时,java和JavaScript都会显示不同的结果。

好吧,我正在阅读关于AES加密的方法和填充方案,一些博客谈论使用CBC模式与NoPadding是不正确的,并且更好/正确使用CBC与Pkcs7或其他填充。

任何人都可以向我解释与此相关的事情吗?

1 个答案:

答案 0 :(得分:5)

如果在ECB / CBC分组密码模式下执行AES加密,则需要填充明文,除非您的明文是块大小的倍数。你当然可以确保你的明文总是精确的N块,但实际上你会创建自己的填充模式。

许多库(例如PHP中的mcrypt)在秘密执行 pad时不指定任何填充。它们只用00个值字节填满最后一个块。这样做的结果是您可以加密 ASCII兼容文本,然后 null终止。在大多数语言中(不使用空终止),也可以使用trim方法删除此填充。然而,这不是官方填充模式。当然,如果您的纯文本不以控制字符结尾,则此方案仅适用于。所以它不适合任何二进制明文。

使用PKCS#7填充肯定更好。删除PKCS#7填充是任何明文的确定性。这意味着您可以加密任何值,包括UTF-16编码的文本和任何二进制值。如果PKCS#7填充不可用,那么自己实现它相对容易 - 这当然值得付出努力。用于CBC模式的PKCS#7填充的唯一缺点是,当明文已经是块大小的N倍时,可能需要额外的填充块。这样做的原因是明文可能会被误解为填充。

请注意,填充和填充错误不适合来检测密文是否在传输过程中发生了变化。 Padding Oracles非常容易实现,并且可以以明文(!!!)的明文大小的128倍显示您的明文。因此,如果要为明文提供完整性和真实性,请使用经过身份验证的操作模式或MAC(HMAC或CMAC)。

如果你真的不能错过用于填充的字节,请查看CTR块或类似的块流操作模式。


修改

还有密文窃取或CTS可用于CBC模式。它使用不多,因为它有三个不同的版本,你应该确保使用哪一个。

现在更常见的是使用计数器模式(CTR模式)或基于它的认证模式(如果完全使用分组密码)。 CTR模式不需要任何填充,因为它是一种流式操作模式。