gpt4 book ai didi

python - 使用 python 和 nodejs 加密和解密

转载 作者:IT老高 更新时间:2023-10-28 23:09:50 25 4
gpt4 key购买 nike

我正在尝试在 Python 中加密某些内容并在 nodejs 应用程序中对其进行解密。

不过,我正在努力让这两个 AES 实现协同工作。这就是我所在的位置。

在 Node 中:

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

显然它们非常接近,但 Node 似乎正在用一些东西填充输出。有什么想法可以让两者互操作吗?

最佳答案

好的,我想通了, Node 使用 OpenSSL,它使用 PKCS5做填充。 PyCrypto 不处理填充,所以我自己做的只是在两者中添加 ' '。

如果我在 python 代码中添加 PKCS5 填充并在 Node 代码中删除填充,它可以工作。

所以更新了工作代码。 Node :

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');

var data = new Buffer(input, 'utf8').toString('binary');

var cipher = crypto.createCipheriv('aes-256-cbc', key, iv.slice(0,16));

// UPDATE: crypto changed in v0.10
// https://github.com/joyent/node/wiki/Api-changes-between-v0.8-and-v0.10
var nodev = process.version.match(/^v(\d+)\.(\d+)/);
var encrypted;

if( nodev[1] === '0' && parseInt(nodev[2]) < 10) {
encrypted = cipher.update(data, 'binary') + cipher.final('binary');
} else {
encrypted = cipher.update(data, 'utf8', '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(/\-/g, '+').replace(/_/g, '/');
// 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));

// UPDATE: crypto changed in v0.10
// https://github.com/joyent/node/wiki/Api-changes-between-v0.8-and-v0.10
var nodev = process.version.match(/^v(\d+)\.(\d+)/);
var decrypted, plaintext;

if( nodev[1] === '0' && parseInt(nodev[2]) < 10) {
decrypted = decipher.update(edata, 'binary') + decipher.final('binary');
plaintext = new Buffer(decrypted, 'binary').toString('utf8');
} else {
plaintext = (decipher.update(edata, 'binary', 'utf8') + decipher.final('utf8'));
}

callback(plaintext);
};

encrypt(input, password, function (encoded) {
console.log(encoded);
decrypt(encoded, password, function (output) {
console.log(output);
});
});

Python:

from Crypto.Cipher import AES
from hashlib import md5
import base64

password = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
input = 'hello world'

BLOCK_SIZE = 16

def pad (data):
pad = BLOCK_SIZE - len(data) % BLOCK_SIZE
return data + pad * chr(pad)

def unpad (padded):
pad = ord(chr(padded[-1]))
return padded[:-pad]

def get_key_iv (password):
m = md5()
m.update(password.encode('utf-8'))
key = m.hexdigest()

m = md5()
m.update((password + key).encode('utf-8'))
iv = m.hexdigest()

return [key,iv]

def _encrypt(data, password):

key,iv = get_key_iv(password)
data = pad(data)

aes = AES.new(key, AES.MODE_CBC, iv[:16])

encrypted = aes.encrypt(data)
return base64.urlsafe_b64encode(encrypted)

def _decrypt(edata, password):
edata = base64.urlsafe_b64decode(edata)
key,iv = get_key_iv(password)

aes = AES.new(key, AES.MODE_CBC, iv[:16])
return unpad(aes.decrypt(edata))


output = _encrypt(input, password)
print(output)
plaintext = _decrypt(output, password)
print(plaintext)

关于python - 使用 python 和 nodejs 加密和解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10548973/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com