0

First of all, I'm a newbie in this subject. This is the first time I need to send encrypted data from front-end to back-end in a secure way.

I'm trying to use CryptoJS to encrypt some sensitive data (credit card information) and send it to my PHP backend, where I need to decrypt it to use with the integration with my payment gateway.

This is my JS code:

let card_number = form.find("input#card_number").val();
let card_holder = form.find("input#card_holder").val();
let card_expiration_date = form.find("input#card_expiration_date").val();
let card_cvv = form.find("input#card_cvv").val();

let key = globalSettings.encryption_key;

card_number = CryptoJS.AES.encrypt(card_number, key);
card_holder = CryptoJS.AES.encrypt(card_holder, key);
card_expiration_date = CryptoJS.AES.encrypt(card_expiration_date, key);
card_cvv = CryptoJS.AES.encrypt(card_cvv, key);

formData = {
    card_number: card_number.toString(),
    card_holder: card_holder.toString(),
    card_expiration_date: card_expiration_date.toString(),
    card_cvv: card_cvv.toString(),
};

For note, the globalSettings object is sent from backend with configured keys. The generated formData object is sent to back-end with no problem. But, when trying to decrypt the values with openssl_decrypt, I'm only getting false results.

Here is my PHP code:

$card_number = $request->get("card_number");
$card_holder = $request->get("card_holder");
$card_expiration_date = $request->get("card_expiration_date");
$card_cvv = $request->get("card_cvv");

$key = ENCRYPTION_KEY;
$method = "AES-256-CBC";

$card_number = openssl_decrypt($card_number, $method, $key);
$card_holder = openssl_decrypt($card_holder, $method, $key);
$card_expiration_date = openssl_decrypt($card_expiration_date, $method, $key);
$card_cvv = openssl_decrypt($card_cvv, $method, $key);

Before applying openssl_decrypt, the variables are exact the same as sent from front-end. But, after applying openssl_decrypt, they are all changed to false, and I can't figure out why and how to fix it to get back decrypted information.

RBFraphael
  • 367
  • 1
  • 3
  • 13
  • What is the purpose of encrypting the data manually? If you use SSL (which you _really_ need to do if you handle payment details), all traffic between the client and server will already be encrypted. That's what it's for, after all! – M. Eriksson Sep 05 '22 at 06:25
  • Yes, I know SSL will handle that. But my client is very rigorous with sensitive data, and his Information Security department asked me to send encrypted data, even using SSL. They have an MITM and DDOS attack history, so this is a way they can feel more secure about users sensitive data. – RBFraphael Sep 05 '22 at 06:29
  • To be honest, you should really educate the client that this won't really make it more secure during transmission. And point out that even big banks and security companies rely on SSL for protecting their traffic. – M. Eriksson Sep 05 '22 at 06:57
  • Does this answer your question? [Encrypt with PHP, Decrypt with Javascript (cryptojs)](https://stackoverflow.com/questions/24337317/encrypt-with-php-decrypt-with-javascript-cryptojs) – Bhaumik Pandhi Sep 05 '22 at 09:00
  • In the CryptoJS code, is `key` a `WordArray` or a string? I guess it's a string. In this case CryptoJS uses a key derivation (`EVP_BytesToKey()`) which is not applied in the PHP code. – Topaco Sep 05 '22 at 09:32
  • @BhaumikPandhi Unfortunately, no. I need to encrypt data with JS, then decrypt in PHP. – RBFraphael Sep 05 '22 at 12:43
  • @Topaco Yes, the key is a string. It is a complex password (32 chars mixing letters, numbers and symbols). Now, how can I apply this derivatiom EVP_BytesToKey you said in PHP ? – RBFraphael Sep 05 '22 at 12:45
  • @RBFraphael, the link I shared works both ways, JavaScript to PHP and only JavaScript or only PHP. – Bhaumik Pandhi Sep 06 '22 at 04:20
  • You can find various `EVP_BytesToKey()` implementations on the web, e.g. [here](https://gist.github.com/ezimuel/67fa19030c75052b0dde278a383eda1b#file-decrypt-php-L43). Note that CryptoJS applies MD5 instead of SHA256 so you've to replace 'sha256' with 'md5' in [line 49](https://gist.github.com/ezimuel/67fa19030c75052b0dde278a383eda1b#file-decrypt-php-L49). – Topaco Sep 06 '22 at 09:11

0 Answers0