0

We encrypted a string in JS with this code by this JS library:

CryptoJS.AES.encrypt("Message", "Key").toString()

and then save it to the database for future use cases. Now we want to decrypt that hash in PHP by this code:

openssl_decrypt( "Message", "aes-128-ctr", "Key")

but it gives us a null value! How can we do it without making any changes in JS code?

Milad Xandi
  • 87
  • 2
  • 10
  • I'm afraid it is impossible, during encryption this library generates two additional keys: IV and Salt, to decrypt you need both of them (in addition to your string key), but result of `toString` contains only salt, so IV is lost – Iłya Bursov Jun 15 '22 at 22:34
  • Yes, Thanks. I knew that but I was looking for an alternative way. now I changed both of them and made a safer & logical code! – Milad Xandi Jun 15 '22 at 22:49

1 Answers1

0

In JS side do this:

    var CryptoJSAesJson = {
      stringify: function (cipherParams) {
        var j = { ct: cipherParams.ciphertext.toString(CryptoJS.enc.Base64) };
        if (cipherParams.iv) j.iv = cipherParams.iv.toString();
        if (cipherParams.salt) j.s = cipherParams.salt.toString();
        return JSON.stringify(j);
      },
      parse: function (jsonStr) {
        var j = JSON.parse(jsonStr);
        var cipherParams = CryptoJS.lib.CipherParams.create({
          ciphertext: CryptoJS.enc.Base64.parse(j.ct),
        });
        if (j.iv) cipherParams.iv = CryptoJS.enc.Hex.parse(j.iv);
        if (j.s) cipherParams.salt = CryptoJS.enc.Hex.parse(j.s);
        return cipherParams;
      },
    };

    let data = CryptoJS.AES.encrypt("Text", "Key", {
      format: CryptoJSAesJson,
    }).toString();

    //store the "data" in DB or another place

and in PHP Side do this:

     function cryptoJsAesDecrypt($passphrase, $jsonString){
         $jsondata = json_decode($jsonString, true);
         $salt = hex2bin($jsondata["s"]);
         $ct = base64_decode($jsondata["ct"]);
         $iv  = hex2bin($jsondata["iv"]);
         $concatedPassphrase = $passphrase.$salt;
         $md5 = array();
         $md5[0] = md5($concatedPassphrase, true);
         $result = $md5[0];
         for ($i = 1; $i < 3; $i++) {
             $md5[$i] = md5($md5[$i - 1].$concatedPassphrase, true);
             $result .= $md5[$i];
         }
         $key = substr($result, 0, 32);
         $data = openssl_decrypt($ct, 'aes-256-cbc', $key, true, $iv);
         return $data;
    }

    echo cryptoJsAesDecrypt("Key",data);
    // will show "Text"

source: This Link

Milad Xandi
  • 87
  • 2
  • 10
  • 4th argument to `openssl_decrypt` should be `OPENSSL_RAW_DATA` instead of true, or you can pass 0 and change `$ct = base64_decode($jsondata["ct"]);` to simple `$ct = $jsondata["ct"];` so decrypt will decode base64 – Iłya Bursov Jun 15 '22 at 23:53