用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