我正在尝试将一些现有的php代码转换为nodejs,但是node js代码返回:
TypeError:Salt必须是缓冲区
我正在使用节点版本=> v8.11.2
PHP代码:
class SecurityModel {
protected $key;
protected $method;
protected $data;
protected $iv;
function __construct($data, $key = 'testing', $method = 'AES-256-CBC',$InitialVector = "aw90rela942f65u2") {
$this->data = $data;
$this->key = $this->passwordDeriveBytes($key, null);
$this->method = $method;
$this->iv = $InitialVector;
}
function passwordDeriveBytes($password, $salt, $iterations = 100, $len = 32) {
$key = $password . $salt;
for($i = 0; $i < $iterations; $i++) {
$key = sha1($key, true);
}
if (strlen($key) < $len) {
$hx = $this->passwordDeriveBytes($password, $salt, $iterations - 1, 20);
$counter = 0;
while (strlen($key) < $len) {
$counter += 1;
$key .= sha1($counter . $hx, true);
}
}
return substr($key, 0, $len);
}
function encrypt(): string {
return openssl_encrypt($this->data, "aes-256-cbc", $this->key, 0, $this->iv);
}
function decrypt(): string {
return openssl_decrypt($this->data, "aes-256-cbc", $this->key, 0, $this->iv);
}
}
$objSecurityModel = new SecurityModel('437217');
$Encrypted = $objSecurityModel->encrypt();
echo "Encrypted :".$Encrypted ."<br>"; //returns-->C9xJGa03dRQx9ePm0nLnHg==
$objSecurityModel = new SecurityModel($Encrypted);
echo "Decrypted::".$objSecurityModel->decrypt(); //returns-->437217
我尝试了一些nodejs
NodeJs代码:
const express = require('express');
const app = express();
var crypto = require('crypto');
key = 'testing'
plaintext = '437217'
iv = 'aw90rela942f65u2'
crypto.pbkdf2('testing', null, 100, 32, 'AES-256-CBC', (err, derivedKey) => {
if (err) throw err;
console.log(derivedKey.toString('hex')); // '3745e48...08d59ae'
key = derivedKey.toString('hex');
});
cipher = crypto.createCipheriv('aes-256-cbc', key,iv)
decipher = crypto.createDecipheriv('aes-256-cbc', key,iv);
var encryptedPassword = cipher.update(plaintext, 'utf8', 'base64');
encryptedPassword += cipher.final('base64')
var decryptedPassword = decipher.update(encryptedPassword, 'base64', 'utf8');
decryptedPassword += decipher.final('utf8');
console.log('original :', plaintext);
console.log('encrypted :', encryptedPassword);
console.log('decrypted :', decryptedPassword);
//PORT
const port = process.env.PORT || 3000;
app.listen(port,() => console.log(`Listening on port ${port}....`));
答案 0 :(得分:1)
PBKDF2是一个很棒的主意,它是PHP代码首先应该完成的工作。不幸的是,passwordDeriveBytes()
内部发生的事情与PBKDF2无关。如果要匹配,则需要像passwordDeriveBytes()
内部那样重现循环。
Oh和“ 盐必须是缓冲区”可以通过将IV转换为带有Buffer.from(iv)
的Buffer来解决(这也是一个好的IV不应不< / em>为字符串,但为随机字节)。
const crypto = require('crypto');
function sha1(input) {
return crypto.createHash('sha1').update(input).digest();
}
function passwordDeriveBytes(password, salt, iterations, len) {
var key = Buffer.from(password + salt);
for(var i = 0; i < iterations; i++) {
key = sha1(key);
}
if (key.length < len) {
var hx = passwordDeriveBytes(password, salt, iterations - 1, 20);
for (var counter = 1; key.length < len; ++counter) {
key = Buffer.concat([key, sha1(Buffer.concat([Buffer.from(counter.toString()), hx]))]);
}
}
return Buffer.alloc(len, key);
}
var password = 'testing';
var plaintext = '437217';
var iv = 'aw90rela942f65u2';
//var key = crypto.pbkdf2Sync(password, '', 100, 32, 'sha1'); // How it should be
var key = passwordDeriveBytes(password, '', 100, 32); // How it is
console.log(key.toString('hex'));
var cipher = crypto.createCipheriv('aes-256-cbc', key, Buffer.from(iv));
var decipher = crypto.createDecipheriv('aes-256-cbc', key, Buffer.from(iv));
var part1 = cipher.update(plaintext, 'utf8');
var part2 = cipher.final();
var encrypted = Buffer.concat([part1, part2]).toString('base64');
var decrypted = decipher.update(encrypted, 'base64', 'utf8');
decrypted += decipher.final();
console.log('original :', plaintext);
console.log('encrypted :', encrypted);
console.log('decrypted :', decrypted);
输出:
df07df624db35d0bcf5fe7ff2dfdfffcef93f098939d750ca55595ae1b33925d
original : 437217
encrypted : C9xJGa03dRQx9ePm0nLnHg==
decrypted : 437217