I have a custom payment method on WordPress that processes the payment through a NodeJS API. For obvious reasons, I should encrypt some data, like credit card numbers and cvv2s.
This is how I encrypt my fields in PHP:
$cvv2 = openssl_encrypt(
$_POST['cvv2'],
'AES-256-CBC',
"2c2702d12c747661358dfe9b77425628", // Testing key, thats why its set like this
0
);
This is the output ciphered text: CRqJRoqHriB7X/u1bwSE1Q==
This is how I try to decrypt in JS
const key = "2cea02d12c747661358dfe9b77425628";
const dec = CryptoJS.AES.decrypt(cvv2,key);
console.log(dec.toString(CryptoJS.enc.Utf8))
But the output is always an empty string.
This is me decrypting it using an online tool
I am really frustrated as I cannot seem to make this work, no matter how much I read online. What could be the problem?
In the CryptoJS code, the key must be passed as WordArray
(using a suitable encoder) and the zero IV (16 0x00 values) used implicitly in the PHP code must be specified explicitly.
The ciphertext must be passed as CipherParams
object or Base64 encoded (the latter is implicitly converted to a CipherParams
object):
const key = CryptoJS.enc.Utf8.parse("2cea02d12c747661358dfe9b77425628");
const iv = CryptoJS.lib.WordArray.create([], 16);
const ciphertext = "CRqJRoqHriB7X/u1bwSE1Q==";
const dec = CryptoJS.AES.decrypt(ciphertext, key, {iv: iv});
console.log(dec.toString(CryptoJS.enc.Base64));
console.log(dec.toString(CryptoJS.enc.Utf8));
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
Note that a static IV is insecure.