使用AES加密时,必须将明文填充到密码块大小。大多数库和标准使用填充,其中填充字节可以从未填充的明文长度确定。在可能的情况下使用随机填充字节有什么好处吗?
我正在实施一种用于存储敏感的每用户和每会话数据的方案。数据通常是JSON编码的键值对,并且可能是短的和重复的。我期待PKCS#5寻求指导,但我计划使用AES加密算法而不是DES3。我正在计划随机IV每个数据项,以及由用户ID和密码或会话ID确定的密钥。
让我感到惊讶的是明文的PKCS#5填充方案。要将密文填充到8字节块,最后添加1到8个字节,填充字节内容反映填充字节数(即01
,0202
,030303
,最多0808080808080808
)。我自己的填充方案是在明文的前面使用随机字节,明文的最后一个字符是添加的填充字节数。
我的理由是在AES-CBC模式下,每个块都是前一个块的密文的函数。这样,每个明文都有一个随机元素,给我另一层保护,免受已知的明文攻击,以及IV和关键问题。由于我的明文预计很短,我不介意将整个解密的字符串保存在内存中,并在正面和背面切片填充。
一个缺点是相同的无拼接明文,IV和密钥会导致不同的密文,使单元测试变得困难(但并非不可能 - 我可以使用伪随机填充生成器进行测试,并使用加密强大的生成器进行生产)。
另一个是,为了强制执行随机填充,我必须添加至少两个字节 - 一个计数和一个随机字节。对于确定性填充,最小值是一个字节,可以用明文存储,也可以存储在密文包装中。
由于像PKCS#5这样备受好评的标准决定使用确定性填充,我想知道是否还有其他我错过的东西,或者我判断它的好处太高了。
答案 0 :(得分:3)
两者,我怀疑。好处是相当小的。
您已经忘记了获取或生成加密质量随机数的运行时成本。在一个极端情况下,当有限的随机性供应(例如某些系统上的/ dev / random)时,您的代码可能需要等待很长时间才能获得更多的随机字节。
另一方面,当您从PRNG获取随机字节时,如果您使用相同的随机源生成密钥,则可能会遇到问题。如果您将加密数据一个接一个地发送给多个收件人,则您已向前一个收件人提供了大量有关PRNG状态的信息,这些信息将用于为您的下一个通信会话选择密钥。如果您的PRNG算法被破坏,这比IMO对完整AES的良好明文攻击更有可能,那么与使用故意确定性填充相比,情况要差得多。
在任何一种情况下,无论你得到填充,它都比PKCS#5填充更加计算密集。
另外,用例如压缩可能重复的数据是相当标准的。在加密之前放气;这减少了数据的冗余,这可能使某些攻击更难以执行。
最后一个建议:使用只有用户名和密码变化的机制来获取密钥是非常危险的。如果您打算使用它,请确保使用没有已知缺陷的哈希算法(不是SHA-1,而不是MD-5)。 cf this slashdot story
希望这有帮助。