python - 用python编写AES-CTR解密例程

标签 python cryptography aes ctr-mode

我有以下代码

func encrypt(key, data string) (string, error) {
    byteKey := []byte(key)
    plaintext := []byte(data)

    block, err := aes.NewCipher(byteKey)
    if err != nil {
        return "", err
    }
    ciphertext := make([]byte, len(plaintext))
    stream := cipher.NewCTR(block, byteKey[aes.BlockSize:])
    stream.XORKeyStream(ciphertext, plaintext)
    return base64.StdEncoding.EncodeToString(ciphertext), nil
}

其中byteKey = []byte("4e8f1670f502a3d40717709e5f80d67c") (不确定这是否是正确的语法,但这是十六进制的关键。)

我的任务是用任何语言编写解密例程,这就是我到目前为止所拥有的:

import base64
from Crypto.Cipher import AES

def decrypt(ct):
        key = '4e8f1670f502a3d40717709e5f80d67c'.decode('hex')
        nonce = 0
        ct1 = base64.b64decode(ct)
        cipher = AES.new(key, mode=AES.MODE_CTR, counter=lambda: nonce)
        print str(cipher.decrypt(ct1))

我做错了什么,我只是不知道是什么。请专家帮忙吗?提前致谢。

最佳答案

提示:想想计数器模式是如何工作的。代码中的初始计数器值是多少,后续值是什么?它们应该是什么?

<小时/>
counter=lambda: nonce

这是一个常量函数,总是返回相同的值,在您的程序中为 0。但这不是您需要传递给 counter 的内容:您需要传递一个在每次调用时返回当前计数器值的函数。例如,如果初始计数器值为 0,则该函数第一次调用时必须返回 0,第二次调用时返回 1,第三次调用时返回 2,依此类推。更准确地说,它必须返回 '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',然后 '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

这里的Python接口(interface)设计得很糟糕。它过于灵活,但这种灵 active 在实践中从来没有用处,并且使得正确使用 API 变得困难。此外,documentation 根本不清楚:

counter (callable) - (Only MODE_CTR). A stateful function that returns the next counter block, which is a byte string of block_size bytes. For better performance, use Crypto.Util.Counter.

事实上,您几乎需要使用Crypto.Util.Counter,不仅仅是为了“性能”,而是为了使计算正确。不要感到难过:你不是第一个被这个绊倒的人。

面对一个你无法理解的 API,你接下来可能会转向 Stack Overflow...这个问题已经在 PyCrypto problem using AES+CTR 得到了解答,但要注意,这个问题已经有 7 年没有正确的答案了,尽管拥有一个被投票并接受的。我的回答展示了如何使用 MODE_CTRcounter

第二个问题可能是初始计数器值。选择 CTR 模式的初始计数器值有两种主要策略:

  • 对于一次性 key ,从 0 开始,并且不要将 ICV 与消息一起传输,因为它是众所周知的常量。
  • 对于多次使用 key ,每次生成一个随机值,并在密文开头发送 ICV。

我不熟悉您发布的加密代码中的 API。但由于它返回与明文长度相同的密文,因此它可能使用恒定的 ICV(这对于一次性 key 来说很好,但如果重复使用 key 则可能是灾难性的),很可能为 0。不过,请检查该文档API。

(如果您需要进一步的编码帮助,请询问 Stack Overflow 而不是 Cryptography ,因为编码问题与 Cryptography.SE 上的主题无关。并且请务必发布 complete code to reproduce the problem ,包括输入和输出。)

关于python - 用python编写AES-CTR解密例程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53276392/

相关文章:

python - 无法通过 pip 安装 python-ldap

python - 在 IPython Notebook 中关闭自动保存

c# - 使用 Interop 处理字节顺序的标准是什么?

Python:变长元组

python - 属性错误 : 'list' object has no attribute 'replace' during change array

java - 如何将 Bouncy CaSTLe SCrypt 字节数组转换为字符串格式或 HexString 格式?

encryption - 为什么在对对称算法的暴力攻击中,尝试一半后有 50% 的机会找到 key ?

go - 如何在Go中解密使用Openssl aes-256-cbc加密的文件

java - 在 Java/grails 中使用 AES 128 加密字符串

encryption - ZigBee 绿色电源 AES-CCM