I am looking at porting a project from PHP to NodeJS and within it contains an encryption/decryption class to encrypt and decrypt strings and I am trying to convert it to NodeJS.
Below is the existing PHP function
public function encrypt($data): string
{
return base64_encode(openssl_encrypt($data, 'AES-256-CBC', $this->cipher_key,
OPENSSL_RAW_DATA, $this->iv));
}
public function decrypt($encryptedString)
{
try
{
return $this->strippadding(openssl_decrypt(base64_decode($encryptedString), 'AES-256-CBC',
$this->cipher_key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->iv));
}
catch (\Exception $e)
{
Logger::log("Failed to decrypt string. Error: " . $e->getMessage());
return $encryptedString;
}
}
private function strippadding($string)
{
error_reporting(0);
$slast = ord(substr($string, -1));
$slastc = chr($slast);
//$pcheck = substr($string, -$slast);
if(preg_match('/'.$slastc.'{'.$slast.'}/', $string)){
return substr($string, 0, strlen($string)-$slast);
} else {
return null;
}
}
And below is my ported code to NodeJS
const encrypt = (data, key, iv) => {
const cipher = crypto.createCipheriv('AES-256-CBC', key, iv);
let encrypted = cipher.update(data, 'utf8', 'base64');
encrypted += cipher.final('base64');
return encrypted;
}
const decrypt = (encryptedString, key, iv) => {
try {
const decipher = crypto.createDecipheriv('AES-256-CBC', key, iv);
decipher.setAutoPadding(false);
let decrypted = decipher.update(encryptedString, 'base64', 'utf-8');
decrypted += decipher.final('utf-8');
return strippadding(decrypted);
return decrypted
} catch (e) {
console.log(`Failed to decrypt string. Error: ${e.message}`);
return encryptedString;
}
}
const strippadding = (string) => {
const slast = string.charCodeAt(string.length - 1);
const slastc = String.fromCharCode(slast);
const regex = new RegExp(`${slastc}{${slast}}`);
if (regex.test(string)) {
return string.substring(0, string.length - slast);
} else {
return null;
}
}
When I try and take an existing encrypted string and use the same key and iv to decrypt it I get a NULL returned as the regex in the strippadding function doesn't seem to work but I can't see why. If I don't use the strippadding and just print the decrypted variable I just get random symbols.
If I try and encrypt a string I then get completely different string to what I'm expecting so I have something not quite right but not sure what.
decrypt()only decrypt ciphertexts fromencrypt()or also other ciphertexts where it is not known whether they are padded or not? If the former, the default unpadding should be used, which reduces the code by about half.