使用python和nodejs进行加密和解密

我正在尝试在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

显然,它们非常接近,但是node似乎在用某些内容填充输出。有什么想法可以使两者互操作吗?

回答:

好的,我已经弄清楚了,节点使用OpenSSL,后者使用PKCS5进行填充。PyCrypto不处理填充,所以我自己做,只是在两者中都添加了’‘。

如果我在python代码中添加PKCS5填充,并在节点代码中删除了填充,则可以使用。

因此更新了工作代码。节点:

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

});

});

蟒蛇:

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(padded[-1])

return padded[:-pad]

def _encrypt(data, nonce, password):

m = md5()

m.update(password)

key = m.hexdigest()

m = md5()

m.update(password + key)

iv = m.hexdigest()

data = pad(data)

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 unpad(aes.decrypt(edata))

output = _encrypt(input, "", password)

print(output)

plaintext = _decrypt(output, "", password)

print("'" + plaintext + "'")

以上是 使用python和nodejs进行加密和解密 的全部内容, 来源链接: utcz.com/qa/416277.html

回到顶部