I have some problem when porting a function from PHP to NodeJS. I have tried implement this PHP code with Node JS, but its not working.
This is the code in PHP
<?php
require_once 'vendor/autoload.php';
// function decrypt
function stringDecrypt($key, $string){
$encrypt_method = 'AES-256-CBC';
// hash
$key_hash = hex2bin(hash('sha256', $key));
// iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
$iv = substr(hex2bin(hash('sha256', $key)), 0, 16);
$output = openssl_decrypt(base64_decode($string), $encrypt_method, $key_hash, OPENSSL_RAW_DATA, $iv);
return $output;
}
?>
This is my code in NodeJs
function decryptResponse(timestamp, string, key) {
var key_hash = hex2bin(crypto.createHash("sha256").update(key).digest('hex'));
var iv = key_hash.substr(0,16);
var decoder = crypto.createDecipheriv('aes-256-cbc', key_hash, iv);
var output = decoder.update(Buffer.from(string).toString('base64'),'base64','utf8') += decoder.final('utf8');
console.log("Decrypt Result : ", output); //Not Showing on Log
}
function hex2bin(hex) {
var bytes = [];
var str;
for(var i=0; i< hex.length-1; i+=2){
bytes.push(parseInt(hex.substr(i, 2), 16));
}
str = String.fromCharCode.apply(String, bytes);
return str;
}
This function is called when I get the response from API and need to send it to the user.
var decompressedResponse = decryptResponse(timestamp, response.data.response, key);
res.send(decompressedResponse);
I need this function to decrypt a response from API so I really need this one working. Thank you for your help.
The hex2bin()
function is not needed and can be removed.
Also, it's easier to determine key and IV as buffer.
The ciphertext is currently Base64 encoded a second time in update()
. To avoid this, it should be passed directly to update()
.
And the concatenation of the results of update()
and final()
call must be done with +
instead of +=
(which is probably just a typo or copy/paste error).
Overall:
function decryptResponse(timestamp, string, key) {
var key_hash = crypto.createHash("sha256").update(key).digest(); // remove hex2bin; use Buffer
var iv = key_hash.slice(0,16); // use Buffer
var decoder = crypto.createDecipheriv('aes-256-cbc', key_hash, iv);
var output = decoder.update(string,'base64','utf8') + decoder.final('utf8'); // don't Base64 encode twice, pass ciphertext directly; apply + instead of +=
console.log("Decrypt Result : ", output);
}
Note that it's insecure to use the key or a part of the key as IV. Usually the (non-secret) IV is randomly generated for each encryption and passed along with the ciphertext (typically concatenated).
Also, using a hash as key derivation function is insecure. Instead, a reliable key derivation function such as PBKDF2 should be applied.