【发布时间】:2021-05-22 15:28:13
【问题描述】:
我正在使用 PyCryptoDome AES CBC 文档的 documentation 中提供的代码。
import json
from base64 import b64encode
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import get_random_bytes
data = b"secret"
key = get_random_bytes(16)
cipher = AES.new(key, AES.MODE_CBC)
ct_bytes = cipher.encrypt(pad(data, AES.block_size))
iv = b64encode(cipher.iv).decode('utf-8')
ct = b64encode(ct_bytes).decode('utf-8')
result = json.dumps({'iv':iv, 'ciphertext':ct})
print(result)
预期的输出是:
{"iv": "bWRHdzkzVDFJbWNBY0EwSmQ1UXFuQT09", "ciphertext": "VDdxQVo3TFFCbXIzcGpYa1lJbFFZQT09"}
但我得到的输出(相同的复制粘贴代码是):
{"iv": "PnMwNa/dPBGSkg5LeJ++1g==", "ciphertext": "OGTvHSp2O4dGgfbKbXpSzA=="}
我认为问题可能是随机键引起的,所以我循环运行了 20 次:
import json
from base64 import b64encode
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import get_random_bytes
print('Result should be like\n{"iv": "bWRHdzkzVDFJbWNBY0EwSmQ1UXFuQT09", "ciphertext": "VDdxQVo3TFFCbXIzcGpYa1lJbFFZQT09"}')
for x in range(0, 20):
data = b"secret"
key = get_random_bytes(16)
cipher = AES.new(key, AES.MODE_CBC)
ct_bytes = cipher.encrypt(pad(data, AES.block_size))
iv = b64encode(cipher.iv).decode('utf-8')
ct = b64encode(ct_bytes).decode('utf-8')
result = json.dumps({'iv':iv, 'ciphertext':ct})
print(result)
遗憾的是,所有结果都相似:
Result should be like
{"iv": "bWRHdzkzVDFJbWNBY0EwSmQ1UXFuQT09", "ciphertext": "VDdxQVo3TFFCbXIzcGpYa1lJbFFZQT09"}
{"iv": "PnMwNa/dPBGSkg5LeJ++1g==", "ciphertext": "OGTvHSp2O4dGgfbKbXpSzA=="}
{"iv": "FR9GQqA3tssPKn2YHhHe4w==", "ciphertext": "FM3CLY51i0Gvctr9efXGDg=="}
{"iv": "ocsVcOggvjUXj8s2IHXbUg==", "ciphertext": "mR3mYEK4M3QhtUmPt6jwuA=="}
{"iv": "TCox/Pfv5Xjkrm8z3weJ0w==", "ciphertext": "DkkGKXvXpV4B8pV5B4ctxw=="}
{"iv": "eZvCrk97EC4eL1kO5PQ+Dg==", "ciphertext": "idaLj7wl/F79qUdzZodbBg=="}
{"iv": "KqwaWZTxU5ZFn6Ekq/wWEg==", "ciphertext": "A25LP0wNTJRkndhvuhuasw=="}
{"iv": "FlFNCnQHmUajP2jNDvIiLw==", "ciphertext": "T9vOu0z9DkUrXCUGqXacxw=="}
{"iv": "U74vTvWZNhKbp5sq9uT9Sg==", "ciphertext": "vfJ1Brftb897O6xTMI3MQg=="}
{"iv": "tIVgKly8wyhpwdoRQ6SzqA==", "ciphertext": "EjnyNuIPVmt7cnEaFSsoww=="}
{"iv": "5qoVwEB7WfHGSGZvHY25Hg==", "ciphertext": "RBxS7gIMAfZqS5a9vTEcjQ=="}
{"iv": "NCHdCr09s9pMQsHK+4ECjA==", "ciphertext": "V8ezqaw8WrrygrokrD48ew=="}
{"iv": "x+T+fM3diahDBie4o7fvpA==", "ciphertext": "0xnjaIArYsfKn5JkjXnniQ=="}
{"iv": "v0r3123VCkZy7zOVixyBkA==", "ciphertext": "J2U0MEHqDEwC45UCY7+SdA=="}
{"iv": "l1iA//cLxESUax39ZanyRw==", "ciphertext": "QLC74BydGuQ1J73PUvKl+Q=="}
{"iv": "FcsfeZ3iCrVVaRsZSm3Gsw==", "ciphertext": "wyiZEo1VpdM/u+ucstzn6Q=="}
{"iv": "av6FSkAzfkOyfLvxDIHY9g==", "ciphertext": "EuexPtCb69+37F9INqWemw=="}
{"iv": "a8F+8OEv1ieHcgwMXocEww==", "ciphertext": "6rd04diPiA7tw/4MgIJsWw=="}
{"iv": "jUY115jhERX2KI+dtVajlQ==", "ciphertext": "TRC5RR3qX6EDjjH1kmO6ew=="}
{"iv": "fcW66kw4gpEWRvNf3AQg7g==", "ciphertext": "o1G6luiDT1Cf2bmZlTu57A=="}
{"iv": "U5FbVnDONa0h4Q6PDJo60A==", "ciphertext": "ilGJKuKNxUxx/Lxz5N85NQ=="}
所以,我的问题是,什么可能导致这种不匹配? 另外,请注意 IV 大小与预期输出相比是错误的
【问题讨论】:
-
只要不指定 IV,就会生成一个随机 IV(参见 PyCryptodome 文档)。随机 IV 和/或随机密钥将为相同的明文生成不同的密文。从这个意义上说,
{"iv": "bWRH...", "ciphertext": "VDdx..."}不是预期的结果,而是可能的结果。但是,已发布示例 / PyCryptodome 文档中的 IV 大小错误(文档中的错误)。对于 AES,IV 为 16 字节长或 24 字节 Base64 编码。 IE。代码工作正常。 -
对于 CBC 模式下的 AES 加密,绝不能重复使用相同的 IV。为了防止没有经验的用户这样做,PyCryptoDome 函数使用随机生成的 IV - 这就是你每轮得到的输出。第二:您没有解释您的“预期”IV 来自哪里 - 它是(已经)Base64 编码输出的 Base64 编码值。当 Base64 解码您的预期值时,您会得到“mdGw93T1ImcAcA0Jd5QqnA==”,它完美解码为 16 字节长的 IV(以十六进制字符串编码 99d1b0f774f5226700700d0977942a9c),因此您的功能一切正常。
-
密文
VDdx...的大小也错误。 IV 和密文是 double Base64 编码的。但是代码(如您的测试所示)仅输出 IV 和密文 single Base64 编码。因此发布的输出与代码不一致。如前所述,文档中的一个错误。 -
@Topaco 你说文档中有一个错误(大小错误),你还说代码可以正常工作,你有一个可以以预期输出大小运行的示例吗?另外,预期输出是指预期输出大小遵循文档说明。
-
或者有没有你建议我应该使用的其他库?
标签: python aes cbc-mode pycryptodome