PHP在JS节点中进行加密和解密



我在PHP中进行了加密,在节点JS中进行了解密。我知道这里面有很多话题。但他们都表示这不起作用。就我而言,确实如此。好吧。

PHP

define('CRYPT_KEY', 'bwAZA48aaYd34PGhBWSutIIFaCu4oAe/Ps24/Rx+bw0=');
class Encryption {
public function encrypt($data) {
$output = false;
$methode = "AES-256-CBC";
$key = base64_decode(CRYPT_KEY);
$ivSize  = openssl_cipher_iv_length($methode);
$ivData  = openssl_random_pseudo_bytes($ivSize);
$encData = openssl_encrypt($data, $methode, $key, OPENSSL_RAW_DATA, $ivData);
$output = base64_encode($ivData . $encData);
return $output;
}
public function decrypt($data) {
$output = false;
$methode = "AES-256-CBC";
$key = base64_decode(CRYPT_KEY);
$ivSize  = openssl_cipher_iv_length($methode);
$data = base64_decode($data);
$ivData   = substr($data, 0, $ivSize);
$encData = substr($data, $ivSize);
$output = openssl_decrypt($encData, $methode, $key, OPENSSL_RAW_DATA, $ivData);
return $output;
}
}
echo $encryption->encrypt('Hello world'); 
// output: 8ZtGcgDeSCN8f+jrZ/W2tWL40DIncjmCwanFiNrEhyE=

节点JS

const key = Buffer.from('bwAZA48aaYd34PGhBWSutIIFaCu4oAe/Ps24/Rx+bw0=', 'base64');
const iv = Buffer.from(crypto.randomBytes(16), 'base64');

function decrypt(data) {
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
const decripted = decipher.update(data, 'base64', 'utf8') + decipher.final('utf8');

return decripted;
}
console.log('Output: ', decrypt('8ZtGcgDeSCN8f+jrZ/W2tWL40DIncjmCwanFiNrEhyE='));

输出的第一部分是加扰

result: ▬�2���◄p��r♣�'Hello world

有人知道为什么会发生这种事吗。我做错什么了吗?

问题的原因是在PHP代码IV和实际密文中被连接在一起,但在NodeJS代码中缺少相应的分隔。相反,一种新的随机IV被错误地使用了
但是,要使解密工作,必须使用与加密相同的IV。因此,IV必须从连接的数据中确定。

IV和密文的分离可以如下进行:

const data = Buffer.from('tIF2bpl7Ro8lZbslAgBqJNqwIqn4pNWZrGkUaWcJQzo=', 'base64');
const iv = data.subarray(0, 16);
const ciphertext = data.subarray(16);

由于密文现在被传递到decrypt()作为缓冲区,而不是Base64编码,因此decrypt()中的解密必须相应地改变:

const decripted = decipher.update(data, '', 'utf8') + decipher.final('utf8');

请注意,发布的NodeJS示例不起作用。它返回一个EVP_DecryptFinal_ex:坏解密错误,表示密钥和密文不相关。

最新更新