我有一个nodejs服务,该服务对需要用Python解密的某些数据使用AES加密。 无论我做什么,我都无法使它正常工作。 NodeJS代码:
const algorithm = 'aes-128-ctr';
function encryptScript(data, key) {
const cipher = crypto.createCipher(algorithm, key);
let crypted = cipher.update(data, 'utf8', 'hex');
crypted += cipher.final('hex');
return crypted;
}
我已经在Python中尝试过
counter = Counter.new(128)
cipher = AES.new(key, AES.MODE_CTR, counter=counter)
print cipher.decrypt(enc.decode("hex"))
但是它不起作用。
我的第一个问题是Python代码不接受长度超过32个字节的键(而Nodejs代码则接受)。
如果我使用NodeJS加密模块,则解密工作正常:
function decryptScript(data, key) {
const decipher = crypto.createDecipher(algorithm, key);
let dec = decipher.update(data, 'hex', 'utf8');
dec += decipher.final('utf8');
return dec;
}
我不知道节点在做什么,但这可能与数据填充有关。
我如何使其工作?
(我更喜欢不需要在NodeJS代码中进行更改而仅在Python脚本中进行更改的解决方案)。
答案 0 :(得分:1)
CreateCipher
使用EVP_BytesToKey
来创建密钥和IV密码(NodeJS代码中称为 key 的实际上是密码)。 Here是EVP_BytesToKey
在Python中的实现。 CreateCipher
的文档中描述了要使用的参数:MD5,无盐,一次迭代。在CTR-mode中,IV通常随每个块以要定义的值开始递增。 CreateCipher
使用用EVP_BytesToKey
确定的IV作为起始值。 CreateCipher
的功能因此可以在Python中实现,如下所示:
import hashlib
from Crypto.Cipher import AES
from Crypto.Util import Counter
...
encrypted = '5e99b5190f12143c057f6bdd8625f958682e737c11e138a2f571c050313dbe1008347604c7c7e8bf506a0a' # Example
# Generate key and iv
keySize = 16
ivSize = 16
digest = hashlib.md5
salt = b''
password = b'123456' # Example
iteration = 1
keyiv = EVP_BytesToKey(keySize, ivSize, digest, salt, password, iteration)
key = keyiv[0]
iv = keyiv[1]
# Define counter
nbits = 128
initial_value = int.from_bytes(iv, byteorder = 'big');
counter = Counter.new(nbits, initial_value = initial_value)
# Decrypt
cipher = AES.new(key, AES.MODE_CTR, counter = counter)
decrypted = cipher.decrypt(bytes.fromhex(encrypted))
print("Decrypted: " + decrypted.decode('utf8'))
密文是使用以下输入通过NodeJS代码生成的:
key = '123456';
data = 'The quick brown fox jumps over the lazy dog';
请注意,CreateCipher
已过时,不应再使用,尤其是不能与CTR模式结合使用。相反,可以使用CreateCipheriv
。在CTR模式下,密钥/ IV对仅使用一次非常重要。否则,安全性将丢失,请参阅here。 CreateCipher
不提供随机性,即相同的密码始终生成相同的密钥和IV,因此始终生成相同的密钥流。因此,如果多次使用相同的密码,则会失去安全性。另一方面,CreateCipheriv
需要一个密钥和一个随机IV。这里的钥匙可以是
只要IV的随机化可以确保键/值对不重复,可以使用多次,请参见here。