【问题标题】:Pycrypto: "Double encrypting" with AES on ECB mode does not yield plaintextPycrypto:在 ECB 模式下使用 AES 进行“双重加密”不会产生明文
【发布时间】:2020-12-19 05:19:23
【问题描述】:

这是 cryptopals 挑战的一部分 (cryptopals.org)

以下代码对上一轮得到的密文进行“加密”操作:

from Crypto.Cipher import AES


def ecb(plaintext, key):
    assert len(plaintext) == 16

    cipher = AES.new(key, AES.MODE_ECB)
    ciphertext = cipher.encrypt(plaintext)

    return ciphertext


if __name__ == '__main__':
    testbytes = b'a' * 16
    key = b'0' * 16

    ciphertext = ecb(testbytes, key)
    plaintext = ecb(ciphertext, key)

    assert testbytes == plaintext


理论上ECB就是这么简单,加解密模式的唯一区别就是明文和密文交换的地方:加密时明文输入密文输出,解密时密文输入明文输出,休息是一样的。由此推断,再次“加密”密文应该产生明文,但这段代码不能那样工作。如果我不得不猜测encryptdecrypt 不仅仅是应用块操作。无论如何,为什么双重加密不能按预期工作?

【问题讨论】:

  • '为什么双重加密不能按预期工作?' - 想一个简单的凯撒式卷曲,其中字母只是移动(例如 3,'e' 将变成 'h')。进行双重加密不会返回“e”而是“k”。所以你需要以相反的顺序来获取原始明文。这与 AES 相同,因为@Topaco 给出的答案是完整的。
  • @MichaelFehr - 但是,OP 的假设并非完全不合理。在某些情况下,加密两次可能会产生明文,例如具有 XOR 操作的一次性填充。但只是不适用于 AES(或凯撒密码)。

标签: python encryption aes


【解决方案1】:

不应该在你的代码中assert testbytes == plaintext 来检验你的假设吗?

无论如何。加密由两部分组成,算法(此处为 AES)和操作模式(此处为 ECB)。算法本身只能加密单个块。操作模式将此扩展到任何长度的明文。为了使您的假设正确,解密和加密的各个处理步骤及其顺序对于这两个部分、算法和操作模式都必须相同。

关于 ECB 模式,您的假设是正确的,因为每个块都是独立处理的(这也使得这种模式不安全)。但是,对于 AES,您的假设不正确,因为解密本质上是按照reverse 的顺序进行加密,有关详细信息,请参阅here

检查后者的最简单方法是只加密一个块而不进行填充。由于 ECB 模式不使用 IV,因此加密简化为 AES 原语本身。不必禁用填充,因为 PyCryptodome 不会隐式填充(与许多其他库相比)。这种情况只对应于您的代码(尽管您必须检查testbytesplaintext 之间的相等性)。结果验证了使用 AES 的双重加密不会产生原始明文。

【讨论】:

  • 我注意到了这个错误并在发帖前纠正了它,但结果还是一样。感谢您的回答,尽管我现在知道原因:加密和解密操作在分组密码中并不相同,我的想法是错误的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-31
  • 1970-01-01
  • 1970-01-01
  • 2013-04-06
相关资源
最近更新 更多