[英]Writing AES-CTR decryption routine in python
我有以下代碼
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\\x00'
,然后是'\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01'
等
Python界面在這里設計不好。 它過於靈活,但是這種靈活性在實踐中從沒有用過,因此很難正確使用API。 此外, 文檔根本不清楚:
counter
(可調用)-(僅MODE_CTR
)。 返回下一個計數器塊的有狀態函數,該計數器塊是block_size
個字節的字節串。 為了獲得更好的性能,請使用Crypto.Util.Counter
。
實際上,您幾乎需要使用Crypto.Util.Counter
,不僅是為了“性能”,還只是為了使計算正確。 別難過:您不是第一個嘗試此操作的人。
面對您無法弄清的API,接下來您可能會轉向Stack Overflow…,這個問題已經在使用AES + CTR的PyCrypto問題中得到了解答,但是請注意,這個問題7年以來沒有一個正確的答案。 ,盡管有人推薦並接受了。 我的答案顯示了如何使用MODE_CTR
和counter
。
第二個問題可能是初始計數器值。 選擇CTR模式的初始計數器值有兩種主要策略:
您發布的加密代碼中的API我不熟悉。 但是,由於它返回的密文長度與明文長度相同,因此它可能使用恆定的ICV(對於一次性密鑰來說是好的,但如果密鑰被重用則會帶來災難性的后果),很可能為0。仍然,請查閱該文檔API。
(如果您需要進一步的編碼幫助,請在Stack Overflow而不是Cryptography上詢問,因為編碼問題在Cryptography.SE上是不重要的。請確保發布完整的代碼以重現該問題 ,包括輸入和輸出。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.