我在JS 中有以下代码
var CryptoJS = require("crypto-js");
function DecodePara(encrypted, key, iv) {
var key = CryptoJS.SHA256(key);
var iv = CryptoJS.SHA256(iv);
var decrypted = CryptoJS.AES.decrypt(encrypted, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.ZeroPadding
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
var encrypted = 'bCjzbWfj7KqtJjCvYpq7Pg=='
var key = 'SNhPDFVEQVWZjsHoyDBXfuWC'
var iv = key.substr(5, 10)
console.log(DecodePara(encrypted, key, iv))
输出="10203050">
返回如预期,我希望通过python获得相同的结果,我已经根据一些研究进行了一些测试,但没有成功。(
我已经尝试了以下代码的变体
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
import hashlib
code = 'bCjzbWfj7KqtJjCvYpq7Pg=='
key = 'SNhPDFVEQVWZjsHoyDBXfuWC'
iv = key[5:15]
key = hashlib.sha256(key.encode('utf-8')).hexdigest()
iv = hashlib.sha256(iv.encode('utf-8')).hexdigest()
def decrypt(encrypted,key,iv):
cipher = AES.new(key, AES.MODE_CBC, iv)
decryptedtext = unpad(cipher.decrypt(encrypted), AES.block_size)
decryptedtextP = decryptedtext.decode("UTF-8")
return decryptedtextP
decrypted = decrypt(code,key,iv)
print(decrypted)
raise ValueError("Incorrect AES key length (%d bytes)" % len(key)) ValueError: Incorrect AES key length (64 bytes)
在Python代码中考虑以下内容:
- 键和IV不能是十六进制编码的,即
hexdigest()
必须替换为digest()
- IV必须被截断为16个字节(隐式地在CryptoJS代码中完成(
- 密文必须是Base64解码的Base64(隐式地在CryptoJS代码中完成(
- 手动删除零填充,例如使用
rstrip(b' ')
,因为PyCryptodome的填充模块不支持零填充
固定代码为:
from Crypto.Cipher import AES
import hashlib
import base64
code = 'bCjzbWfj7KqtJjCvYpq7Pg=='
key = 'SNhPDFVEQVWZjsHoyDBXfuWC'
iv = key[5:15]
key = hashlib.sha256(key.encode('utf-8')).digest() # replace hexdigest() by digest
iv = hashlib.sha256(iv.encode('utf-8')).digest()[0:16] # replace hexdigest() by digest; truncate the IV to 16 bytes
def decrypt(encrypted,key,iv):
cipher = AES.new(key, AES.MODE_CBC, iv)
decryptedtext = cipher.decrypt(base64.b64decode(encrypted)) # Base64 decode the ciphertext
decryptedtextP = decryptedtext.rstrip(b' ').decode("UTF-8") # remove the Zero padding
return decryptedtextP
decrypted = decrypt(code,key,iv)
print(decrypted) # 10203050
请记住:
- 从密钥派生IV是不安全的,因为如果密钥是固定的,这会导致密钥/IV对的重用。相反,每次加密都应该使用随机IV
- 零填充不可靠。相反,应该使用PKCS#7填充(PyCryptodome的填充模块也支持它(
- 使用摘要作为密钥派生函数是一个漏洞。相反,应该应用诸如Argon2或PBKDF2之类的专用密钥推导函数