我有以下代码
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) - (OnlyMODE_CTR
). A stateful function that returns the next counter block, which is a byte string ofblock_size
bytes. For better performance, useCrypto.Util.Counter
.
事实上,您几乎需要使用Crypto.Util.Counter
,不仅仅是为了“性能”,而是为了使计算正确。不要感到难过:你不是第一个被这个绊倒的人。
面对一个你无法理解的 API,你接下来可能会转向 Stack Overflow...这个问题已经在 PyCrypto problem using AES+CTR 得到了解答,但要注意,这个问题已经有 7 年没有正确的答案了,尽管拥有一个被投票并接受的。我的回答展示了如何使用 MODE_CTR
和 counter
。
第二个问题可能是初始计数器值。选择 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/