【问题标题】:PyCryptoDome AES CBC documentation code gives different outputPyCryptoDome AES CBC 文档代码给出不同的输出
【发布时间】: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


【解决方案1】:

事实证明代码正在运行,并且文档的输出有问题,请记住尝试解码以将 IV 和密码解码为 HEX 时

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-10
    • 1970-01-01
    • 1970-01-01
    • 2018-09-20
    • 2017-06-10
    • 1970-01-01
    • 2021-04-13
    • 1970-01-01
    相关资源
    最近更新 更多