我尝试用Python加密一些内容,然后在nodejs应用程序中解密。
我正在努力让这两个AES实现一起工作。这里是我在哪里。
在节点中:
var crypto = require('crypto');
var password = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
var input = 'hello world';
var encrypt = function (input, password, callback) {
var m = crypto.createHash('md5');
m.update(password)
var key = m.digest('hex');
m = crypto.createHash('md5');
m.update(password + key)
var iv = m.digest('hex');
// add padding
while (input.length % 16 !== 0) {
input += ' ';
}
var data = new Buffer(input, 'utf8').toString('binary');
var cipher = crypto.createCipheriv('aes-256-cbc', key, iv.slice(0,16));
var encrypted = cipher.update(data, 'binary') + cipher.final('binary');
var encoded = new Buffer(encrypted, 'binary').toString('base64');
callback(encoded);
};
var decrypt = function (input, password, callback) {
// Convert urlsafe base64 to normal base64
var input = input.replace('-', '+').replace('/', '_');
// Convert from base64 to binary string
var edata = new Buffer(input, 'base64').toString('binary')
// Create key from password
var m = crypto.createHash('md5');
m.update(password)
var key = m.digest('hex');
// Create iv from password and key
m = crypto.createHash('md5');
m.update(password + key)
var iv = m.digest('hex');
// Decipher encrypted data
var decipher = crypto.createDecipheriv('aes-256-cbc', key, iv.slice(0,16));
var decrypted = decipher.update(edata, 'binary') + decipher.final('binary');
var plaintext = new Buffer(decrypted, 'binary').toString('utf8');
callback(plaintext);
};
encrypt(input, password, function (encoded) {
console.log(encoded);
decrypt(encoded, password, function (output) {
console.log(output);
});
});
这会产生输出:
BXSGjDAYKeXlaRXVVJGuREKTPiiXeam8W9e96Nknt3E=
hello world
Python皮
from Crypto.Cipher import AES
from hashlib import md5
import base64
password = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
input = 'hello world'
def _encrypt(data, nonce, password):
m = md5()
m.update(password)
key = m.hexdigest()
m = md5()
m.update(password + key)
iv = m.hexdigest()
# pad to 16 bytes
data = data + " " * (16 - len(data) % 16)
aes = AES.new(key, AES.MODE_CBC, iv[:16])
encrypted = aes.encrypt(data)
return base64.urlsafe_b64encode(encrypted)
def _decrypt(edata, nonce, password):
edata = base64.urlsafe_b64decode(edata)
m = md5()
m.update(password)
key = m.hexdigest()
m = md5()
m.update(password + key)
iv = m.hexdigest()
aes = AES.new(key, AES.MODE_CBC, iv[:16])
return aes.decrypt(edata)
output = _encrypt(input, "", password)
print(output)
plaintext = _decrypt(output, "", password)
print(plaintext)
这将生成输出
BXSGjDAYKeXlaRXVVJGuRA==
hello world
显然它们非常接近,但是节点似乎在输出中填充了一些东西。有什么想法吗?我如何才能让这两个节点互操作?
4条答案
按热度按时间8i9zcol21#
好的,我已经弄明白了,节点使用OpenSSL,它使用PKCS5来做填充。PyCrypto不处理填充,所以我自己做,只是在两者中都添加“”。
如果我在python代码中添加PKCS5填充并删除节点代码中的填充,它就能工作。
因此更新了工作代码。节点:
Python:
agxfikkp2#
在尝试使用Python 3.8运行Python脚本时,我遇到了以下错误:
密码应为:
我还得到了以下错误:
我可以通过在key后添加以下行来修复它:
python脚本应按如下方式工作:
xoefb8l83#
对于任何一个和我相似的人,他在python中找到了一种简单的方法来为AES加密和解密,在node.js中做了同样的事情。这里的类支持AES的不同位,以及在node.js中产生相同结果的十六进制和base64编码。
还需要注意的是,如果您缺少软件包Crypto,您可以简单地安装它
python的代码如下:
下列是使用类别的范例:
加密示例:
解密示例:
xriantvc4#
因为我在Python 3.10.7和Node.js v18.6.0上花了太多的时间。
下面是两种语言之间完全兼容的工作代码示例。
只需要密码即可获得与预期相同的值:)
注意
pycryptodome
对于Python是必需的。代码应该调整以支持不同的算法。第一个
帮助来自: