Pycrypto:"Double encrypting" 在 ECB 模式下使用 AES 不会产生明文
Pycrypto: "Double encrypting" with AES on ECB mode does not yield plaintext
这是 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就这么简单,加解密方式的唯一区别就是那些明文和密文互换的地方:加密时输入明文,输出密文,解密时输入密文,输出明文输出,其余相同。由此推断,再次“加密”密文应该会产生明文,但这段代码并不是那样工作的。如果我不得不猜测 encrypt
和 decrypt
不仅仅是应用块操作。无论如何,为什么双重加密没有按预期工作?
它不应该在你的代码中 assert testbytes == plaintext
来检验你的假设吗?
总之。加密由两部分组成,算法(此处为 AES)和操作模式(此处为 ECB)。该算法本身只能加密单个块。操作模式将其扩展到任何长度的明文。因此,您的假设是正确的,各个处理步骤及其解密和加密的顺序对于两个部分、算法和操作模式必须相同。
关于 ECB 模式,你的假设是正确的,因为每个块都是独立于另一个块处理的(这也使得这种模式不安全)。但是,对于 AES,您的假设是不正确的,因为解密基本上是按 reverse
顺序进行加密的,有关详细信息,请参阅 here.
检查后者的最简单方法是只加密一个块而不进行填充。由于 ECB 模式不使用 IV,因此加密被简化为 AES 原语本身。不必禁用填充,因为 PyCryptodome 不会隐式填充(与许多其他库相反)。这种情况恰好对应于您的代码(尽管您必须检查 testbytes
和 plaintext
之间的相等性)。结果验证使用 AES 的双重加密不会产生原始明文。
这是 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就这么简单,加解密方式的唯一区别就是那些明文和密文互换的地方:加密时输入明文,输出密文,解密时输入密文,输出明文输出,其余相同。由此推断,再次“加密”密文应该会产生明文,但这段代码并不是那样工作的。如果我不得不猜测 encrypt
和 decrypt
不仅仅是应用块操作。无论如何,为什么双重加密没有按预期工作?
它不应该在你的代码中 assert testbytes == plaintext
来检验你的假设吗?
总之。加密由两部分组成,算法(此处为 AES)和操作模式(此处为 ECB)。该算法本身只能加密单个块。操作模式将其扩展到任何长度的明文。因此,您的假设是正确的,各个处理步骤及其解密和加密的顺序对于两个部分、算法和操作模式必须相同。
关于 ECB 模式,你的假设是正确的,因为每个块都是独立于另一个块处理的(这也使得这种模式不安全)。但是,对于 AES,您的假设是不正确的,因为解密基本上是按 reverse
顺序进行加密的,有关详细信息,请参阅 here.
检查后者的最简单方法是只加密一个块而不进行填充。由于 ECB 模式不使用 IV,因此加密被简化为 AES 原语本身。不必禁用填充,因为 PyCryptodome 不会隐式填充(与许多其他库相反)。这种情况恰好对应于您的代码(尽管您必须检查 testbytes
和 plaintext
之间的相等性)。结果验证使用 AES 的双重加密不会产生原始明文。