3

我正在使用库 1 Aes 算法实现,现在我想将其更改为库 2 的另一个实现,它工作正常,但问题是它给了我来自库 1 的差异加密数据,是否可以使用 ECB 模式 128 位的 Aes 实现相同的密钥和纯文本,但仅在密文(加密数据)方面不同,用于 2 种不同的实现?

我发现另一件事是,如果我传递小于 16 字节的输入字节,那么两个库的加密数据就会匹配,但在 library1 中解密再次完美,但在 library2 中它显示的加密和解密是相同的(不完全解密到原文)会有什么问题?

4

3 回答 3

4

鉴于您评论小于 16 字节的字符串导致相同的输出,以及您使用 ECB(您永远不应该使用),我怀疑您的库之一实际上并未使用 ECB,而是默认为 CBC(其中是一个更好的默认值)并且您将 NULL IV 传递给 CBC。如果我的理论是正确的,那么您应该期望前 16 个字节始终相同,并且在那之后开始出现差异。

最好的解决方案是将所有代码从 ECB(除了一些非常罕见的情况外,在所有情况下都严重损坏)转换为 CBC 或您可以找到的任何其他模式。CBC 是最常见的,您需要将随机生成的 IV 传递给它。

如果切换模式是不可能的,我会调查你的第二个库并确定如何将它设置为 ECB 模式,它目前可能不在。应该警告依赖你的加密的人,使用 ECB 模式会泄露有关明文的重要信息。有时它几乎没有加密。请参阅Wikipedia上的条目,以获得一个很好的视觉示例,说明它到底有多糟糕。这不是理论上的攻击。真的,真的坏了。

于 2012-10-23T02:04:35.293 回答
3

是的,正如评论所指出的那样,这是可能的。加密旨在显示输出的巨大变化,而输入的微小变化。理想情况下,输入中的一位更改将更改输出中 50% 的位。

避免大多数问题的方法是明确指定所有内容。不要依赖默认值,因为如果两个库之间的默认值不同,那么输出就会不同。

  1. 显式指定字符编码以将字符转换为字节。UTF-8 很常见。

  2. 明确指定您使用的加密模式。CBC 或 CTR 模式,如果您不希望包含身份验证,则为 GCM。

  3. 最好使用字节而不是字符明确指定 IV。

  4. 明确指定要使用的填充。PKCS7(又名 PKCS5)很常见。

如果您仍然遇到问题,请检查两个库的所有内容是否逐字节相同。不要检查字符,而是检查字节。也就是说,在将它们转换为字节数组之后以及在将它们传递给加密方法之前立即检查它们。

附带说明一下,ECB 模式不安全并且会泄露信息。它仅对测试密码方法的操作有用。正如我上面建议的那样,使用 CBC、CTR 或 GCM 模式。这些模式是安全的,GCM 包括身份验证。

于 2012-10-19T12:10:52.183 回答
1

这里已经有很多正确的答案了。唯一想提的,之前没提过的。

是否可以使用 ECB 模式 128 位的 Aes 实现,具有相同的密钥和纯文本,但仅在 2 个不同实现的密文(加密数据)上有所不同?

在这种情况下,如果算法实现正确,相同的输入(纯文本、模式、IV、填充)应该产生相同的输出(密文)。

在这种情况下,如果您使用两个已建立的库,则很可能是前面提到的问题之一(输入之一的差异、编码等)。

于 2012-10-19T17:47:03.740 回答