使用 ase256 加密在 python 和 nodejs 中给出不同的输出
encrypt using ase256 gives different output in python and nodejs
我正在尝试使用密钥 = "secret_key" 和文本“11869021012”加密字符串“1”。早些时候我在 nodejs 中写过这个。现在我想把它移植到 python。但令人惊讶的是,两者都给出了不同的输出。
var crypto = require('crypto');
function getBytes (str) {
let bytes = [], char;
str = encodeURI(str);
while (str.length) {
char = str.slice(0, 1);
str = str.slice(1);
if ('%' !== char) {
bytes.push(char.charCodeAt(0));
} else {
char = str.slice(0, 2);
str = str.slice(2);
bytes.push(parseInt(char, 16));
}
}
return bytes;
};
function getIV (str, bytes){
iv = getBytes(str);
if(!bytes) bytes = 16;
for(let i=iv.length;i<bytes;i++) {
iv.push(0);
}
return Buffer.from(iv);
};
function getKey (pwd){
pwd = Buffer.from(getBytes(pwd), 'utf-8');
let hash = crypto.createHash('sha256');
pwd = hash.update(pwd).digest();
return pwd;
};
function createCipherIV (algorithm, input_key, iv_input, text){
let iv = getIV(iv_input);
let key = getKey(input_key);
let cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update(text)
encrypted += cipher.final('base64');
return encrypted;
}
output = createCipherIV('aes256', 'secret_key', '11869021012', '1')
console.log(output)
这会产生输出:
s6LMaE/YRT6y8vr2SehLKw==
python代码:
# AES 256 encryption/decryption using pycrypto library
import base64
import hashlib
from Crypto.Cipher import AES
from Crypto import Random
BLOCK_SIZE = 16
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]
password = "secret_key"
def encrypt(raw, password):
private_key = hashlib.sha256(bytearray(password, "utf-8")).digest()
raw = pad(raw)
iv = b'11869021012\x00\x00\x00\x00\x00'
cleartext = bytearray(raw, 'utf-8')
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return base64.b64encode(iv + cipher.encrypt(cleartext))
# First let us encrypt secret message
encrypted = encrypt("1", password)
print(encrypted)
这会产生输出:
MTE4NjkwMjEwMTIAAAAAALOizGhP2EU+svL69knoSys=
我这里使用了aes256算法来加密消息。
显然它们非常接近,但节点似乎用一些额外的字节填充输出。我有什么想法可以让两者互操作吗?
首先,在安全的加密系统中,您应该期望每次加密时的输出都是不同的,即使使用相同的代码也是如此。你的那个事实并不表明它是一个不安全的密码。通常这是通过添加随机 IV 来完成的。
你的 IV 是“11869021012”,这太可怕了(因为它不是随机的,甚至不是 16 字节),但看起来你在两者中使用它的方式相同,所以没关系。
您的密码是字符串的 SHA-256,这是一种创建密钥的糟糕方法,但是,您似乎在两种情况下都以相同的方式进行操作,所以没关系。
您的问题是 Python 代码发出 IV 后跟密文。您的 JS 代码不会发出 IV;它只发出密文。所以你的意思可能是 Python:
return base64.b64encode(cipher.encrypt(cleartext))
或者你需要修改 JavaScript 在 Base64 编码之前将 IV 和密文粘合在一起。
我正在尝试使用密钥 = "secret_key" 和文本“11869021012”加密字符串“1”。早些时候我在 nodejs 中写过这个。现在我想把它移植到 python。但令人惊讶的是,两者都给出了不同的输出。
var crypto = require('crypto');
function getBytes (str) {
let bytes = [], char;
str = encodeURI(str);
while (str.length) {
char = str.slice(0, 1);
str = str.slice(1);
if ('%' !== char) {
bytes.push(char.charCodeAt(0));
} else {
char = str.slice(0, 2);
str = str.slice(2);
bytes.push(parseInt(char, 16));
}
}
return bytes;
};
function getIV (str, bytes){
iv = getBytes(str);
if(!bytes) bytes = 16;
for(let i=iv.length;i<bytes;i++) {
iv.push(0);
}
return Buffer.from(iv);
};
function getKey (pwd){
pwd = Buffer.from(getBytes(pwd), 'utf-8');
let hash = crypto.createHash('sha256');
pwd = hash.update(pwd).digest();
return pwd;
};
function createCipherIV (algorithm, input_key, iv_input, text){
let iv = getIV(iv_input);
let key = getKey(input_key);
let cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update(text)
encrypted += cipher.final('base64');
return encrypted;
}
output = createCipherIV('aes256', 'secret_key', '11869021012', '1')
console.log(output)
这会产生输出:
s6LMaE/YRT6y8vr2SehLKw==
python代码:
# AES 256 encryption/decryption using pycrypto library
import base64
import hashlib
from Crypto.Cipher import AES
from Crypto import Random
BLOCK_SIZE = 16
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]
password = "secret_key"
def encrypt(raw, password):
private_key = hashlib.sha256(bytearray(password, "utf-8")).digest()
raw = pad(raw)
iv = b'11869021012\x00\x00\x00\x00\x00'
cleartext = bytearray(raw, 'utf-8')
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return base64.b64encode(iv + cipher.encrypt(cleartext))
# First let us encrypt secret message
encrypted = encrypt("1", password)
print(encrypted)
这会产生输出:
MTE4NjkwMjEwMTIAAAAAALOizGhP2EU+svL69knoSys=
我这里使用了aes256算法来加密消息。 显然它们非常接近,但节点似乎用一些额外的字节填充输出。我有什么想法可以让两者互操作吗?
首先,在安全的加密系统中,您应该期望每次加密时的输出都是不同的,即使使用相同的代码也是如此。你的那个事实并不表明它是一个不安全的密码。通常这是通过添加随机 IV 来完成的。
你的 IV 是“11869021012”,这太可怕了(因为它不是随机的,甚至不是 16 字节),但看起来你在两者中使用它的方式相同,所以没关系。
您的密码是字符串的 SHA-256,这是一种创建密钥的糟糕方法,但是,您似乎在两种情况下都以相同的方式进行操作,所以没关系。
您的问题是 Python 代码发出 IV 后跟密文。您的 JS 代码不会发出 IV;它只发出密文。所以你的意思可能是 Python:
return base64.b64encode(cipher.encrypt(cleartext))
或者你需要修改 JavaScript 在 Base64 编码之前将 IV 和密文粘合在一起。