在 AES 加密中填充随机数据有好处吗?

Posted

技术标签:

【中文标题】在 AES 加密中填充随机数据有好处吗?【英文标题】:Is there a benefit to padding with random data in AES encryption? 【发布时间】:2011-01-21 19:06:14 【问题描述】:

使用 AES 加密时,明文必须填充到密码块大小。大多数库和标准都使用填充,其中填充字节可以从未填充的明文长度确定。尽可能使用随机填充字节有什么好处吗?

我正在实施一种方案来存储敏感的每用户和每会话数据。数据通常是 JSON 编码的键值对,并且可能很短且重复。我正在向PKCS#5 寻求指导,但我计划将 AES 用于加密算法而不是 DES3。我计划为每个数据项创建一个随机 IV,以及一个由用户 ID 和密码或会话 ID 确定的密钥(视情况而定)。

让我吃惊的是 PKCS#5 明文填充方案。要将密文填充到 8 字节块中,在末尾添加 1 到 8 个字节,填充字节内容反映填充字节数(即010202030303,最多 0808080808080808 )。我自己的填充方案是在明文前面使用随机字节,明文的最后一个字符是添加的填充字节数。

我的理由是,在 AES-CBC 模式下,每个块都是前一个块的密文的函数。这样,每个明文都会有一个随机元素,为我提供另一层保护,免受已知的明文攻击,以及 IV 和关键问题。由于我的明文预计会很短,我不介意将整个解密的字符串保存在内存中,并从前后切掉填充。

一个缺点是相同的未填充明文、IV 和密钥会导致不同的密文,从而使单元测试变得困难(但并非不可能 - 我可以使用伪随机填充生成器进行测试,并使用加密强的生成器进行生产)。

另一个是,为了强制执行随机填充,我必须添加至少两个字节 - 一个计数和一个随机字节。对于确定性填充,最小值为一个字节,与明文一起存储或在密文包装器中存储。

由于像 PKCS#5 这样备受推崇的标准决定使用确定性填充,我想知道是否还有其他我遗漏的东西,或者我认为好处太高了。

【问题讨论】:

【参考方案1】:

两者,我怀疑。好处是相当少的。

您忘记了获取或生成加密质量随机数的运行时成本。在一个极端情况下,当有限的随机性可用时(例如某些系统上的 /dev/random),您的代码可能需要等待很长时间才能获得更多随机字节。

在另一个极端,当您从 PRNG 获取随机字节时,如果您使用相同的随机源来生成密钥,您可能会遇到问题。如果您一个接一个地向多个收件人发送加密数据,则您已向前一个收件人提供了有关 PRNG 状态的一大堆信息,这些信息将用于为您的下一个通信会话选择密钥。如果您的 PRNG 算法曾经被破坏,这比对完整 AES 的良好明文攻击更有可能是 IMO,那么与使用故意确定性填充相比,您的情况要糟糕得多。

在任何一种情况下,无论您得到填充,它的计算量都比 PKCS#5 填充更多。

顺便说一句,使用例如压缩可能重复的数据是相当标准的。加密前放气;这减少了数据中的冗余,这会使某些攻击更难执行。

最后一个建议:使用仅用户名和密码不同的机制派生密钥是非常危险的。如果要使用它,请确保使用没有已知缺陷的哈希算法(不是 SHA-1,不是 MD-5)。 cfthis slashdot story

希望这会有所帮助。

【讨论】:

优秀的分数。我想我会为密钥和 IV 端保存我的加密质量随机数。我正在寻找 PBKDF2 的密钥派生,但它使用 SHA-1。 PBKDF2 在设计上是可插拔的;原则上,您可以使用更强大的东西,例如 SHA-256(或 SHA-3,一旦我们知道那是什么)。当然,单个 PBKDF2 实现可能不允许您指定要使用的伪随机函数。 我最终使用了 Python (dlitz.net/software/python-pbkdf2) 的 PBKDF2 包,它可以使用不同的散列函数,并且我使用的是 SHA-256。经过一些实验,我很乐意使用压缩和 PKCS#5 样式的填充,并为关键方面保存强大的随机数生成器。

以上是关于在 AES 加密中填充随机数据有好处吗?的主要内容,如果未能解决你的问题,请参考以下文章

AES加密算法在Linux下出现随机加密结果

随机数在密码学中的作用

AES加密 — 详解

AES-128-CBC加密过程中,我想随机产生16位的向量,希望各位能给我一下C语言代码的实现。

Openssl CMS 在 ruby​​ 中加密

aes加密安全吗