代码之家  ›  专栏  ›  技术社区  ›  shad0w_wa1k3r

PyCryptoDome:AES-256使用相同的密钥和数据提供不同的输出

  •  3
  • shad0w_wa1k3r  · 技术社区  · 6 年前

    以下代码生成不同的 ciphertext 每次我执行它,这应该不会发生,因为;每次执行传递的数据都是相同的。

    from Crypto.Cipher import AES
    from Crypto.Util.Padding import pad
    from base64 import b64encode, b64decode
    
    key = '/I02fMuSSvnouuu+/vyyD7NuSEVDB/0gte/z50dM0b4='
    data = 'hello world!'
    
    cipher = AES.new(b64decode(key), AES.MODE_CBC)
    padded_data = pad(data.encode(), cipher.block_size)
    print(b64encode(padded_data))
    # b'aGVsbG8gd29ybGQhBAQEBA=='
    ciphertext = cipher.encrypt(padded_data)
    print(b64encode(ciphertext))
    # b'rEHH0MWIWCWUldjYBco9TA=='
    ciphertext = cipher.encrypt(padded_data)
    print(b64encode(ciphertext))
    # b'FTpLrkZttDxMlpre3Kq8qQ=='
    

    实际上,我正在尝试将一个示例PHP代码复制到Python中,PHP代码提供相同的输出,而我的Python代码提供不同的输出,没有一个与PHP代码匹配。

    Python版本3.6。x个
    PyCryptoDome版本3.4.7

    2 回复  |  直到 6 年前
        1
  •  4
  •   SquareRootOfTwentyThree    6 年前

    每次生成 带Pycryptodome 在CBC模式下创建并使用AES密码对象,即随机IV。可以通过调用 iv (例如 cipher.iv ).

    唯一(且不可预测)IV实现了将输出随机化的目标,即使同一消息被多次加密(使用相同的密钥),这是攻击者经常可以利用的信息。

    您不显示PHP代码,但如果其输出显示 不是 每次更改,都意味着IV已修复,代码存在安全漏洞。

        2
  •  3
  •   shad0w_wa1k3r    6 年前

    我忘了通过 iv parameter 在创建 cipher 对象

    应该是这样的-

    cipher = AES.new(b64decode(key), AES.MODE_CBC, iv=b'0123456789abcdef')
    

    是的,没错 pointed out by Rawing ,重复使用相同的 密码 要加密的对象将给出不同的结果,但如果重建 密码 对象

    cipher = AES.new(b64decode(key), AES.MODE_CBC, iv=b'0123456789abcdef')
    padded_data = pad(data.encode(), cipher.block_size)
    print(b64encode(padded_data))
    # b'aGVsbG8gd29ybGQhBAQEBA=='
    ciphertext = cipher.encrypt(padded_data)
    print(b64encode(ciphertext))
    # b'8G0KL2UiCv7Uo+pKMm9G+A=='
    ciphertext = cipher.encrypt(padded_data)
    print(b64encode(ciphertext))
    # b'tBXcf/Nf6MtxM1ulzNnIlw=='
    
    
    cipher = AES.new(b64decode(key), AES.MODE_CBC, iv=b'0123456789abcdef')
    padded_data = pad(data.encode(), cipher.block_size)
    ciphertext = cipher.encrypt(padded_data)
    print(b64encode(ciphertext))
    # b'8G0KL2UiCv7Uo+pKMm9G+A=='