用python编写AES-CTR解密例程

用python编写AES-CTR解密例程,python,cryptography,aes,ctr-mode,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))

我有以下代码

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=[]字节(“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))

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

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


这是一个常量函数,它总是返回相同的值,即程序中的0。但这不是您需要传递给
计数器的内容:您需要传递一个函数,该函数在每次调用时返回当前计数器值。例如,如果初始计数器值为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'>,等等

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

计数器
(可调用)-(仅限)。一种有状态函数,返回下一个计数器块,即
block\u size
字节的字节字符串。要获得更好的性能,请使用

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

面对一个您无法理解的API,接下来您可能会转向Stack Overflow…这个问题已经在上得到了回答,但请注意,7年来,这个问题一直没有一个正确的答案,尽管有一个经过投票并被接受的答案。我的答案显示了如何使用
模式\u CTR
计数器

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

  • 对于一次性使用的密钥,从0开始,不要发送带有消息的ICV,因为它是一个众所周知的常数
  • 对于多用途密钥,每次生成一个随机值,并在密文开头发送ICV
我不熟悉你发布的加密代码中的API。但由于它返回的密文长度与明文相同,因此它可能使用一个常量ICV(对于单次使用的密钥来说这是很好的,但是如果重复使用密钥则是灾难性的),很可能是0。不过,请查看该API的文档

(如果您需要进一步的编码帮助,请继续询问,而不是询问,因为编码问题在Cryptography.SE.上是离题的,请务必张贴,包括输入和输出。)

counter=lambda: nonce