Skip to content

Instantly share code, notes, and snippets.

@huzemin
Created December 3, 2019 06:47
Show Gist options
  • Save huzemin/e8d7a904cec55d4d7635c9322f143c42 to your computer and use it in GitHub Desktop.
Save huzemin/e8d7a904cec55d4d7635c9322f143c42 to your computer and use it in GitHub Desktop.
laravel Encrypt convert to CryptoJS in Javascript
import CryptoJS from "crypto-js";
const LaravelEncrypt = function (key) {
this.key = key;
}
LaravelEncrypt.prototype.decrypt = function (encryptStr) {
encryptStr = CryptoJS.enc.Base64.parse(encryptStr);
let encryptData = encryptStr.toString(CryptoJS.enc.Utf8);
encryptData = JSON.parse(encryptData);
let iv = CryptoJS.enc.Base64.parse(encryptData.iv);
var decrypted = CryptoJS.AES.decrypt(encryptData.value, CryptoJS.enc.Utf8.parse(this.key), {
iv : iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
decrypted = CryptoJS.enc.Utf8.stringify(decrypted);
return decrypted;
};
LaravelEncrypt.prototype.encrypt = function (data) {
let iv = CryptoJS.lib.WordArray.random(16),
key = CryptoJS.enc.Utf8.parse(this.key);
let options = {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
};
let encrypted = CryptoJS.AES.encrypt(data, key, options);
encrypted = encrypted.toString();
iv = CryptoJS.enc.Base64.stringify(iv);
let result = {
iv: iv,
value: encrypted,
mac: CryptoJS.HmacSHA256(iv + encrypted, key).toString()
}
result = JSON.stringify(result);
result = CryptoJS.enc.Utf8.parse(result);
return CryptoJS.enc.Base64.stringify(result);
};
export default LaravelEncrypt;
@zlAxel
Copy link

zlAxel commented Oct 24, 2023

@Sandeepa-Ceylonsoft

This is my JS code.

    let iv = CryptoJS.lib.WordArray.random(16),
        // Remove 'base64' part from the .env's APP_KEY
        key = CryptoJS.enc.Base64.parse(appKey.slice(7));
    let options = {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7,
    };
    // I'm using JSON.stringify(data) instead of just data
    let encrypted = CryptoJS.AES.encrypt(JSON.stringify(data), key, options);
    encrypted = encrypted.toString();
    iv = CryptoJS.enc.Base64.stringify(iv);
    let result = {
        iv: iv,
        value: encrypted,
        mac: CryptoJS.HmacSHA256(iv + encrypted, key).toString(),
    };
    result = JSON.stringify(result);
    result = CryptoJS.enc.Utf8.parse(result);
    return CryptoJS.enc.Base64.stringify(result);

Then, use decrypt inside laravel without unserializing. decrypt(encryptedData, unserialize:false);

You literally saved my life, thanks for your code.
I tried everything for something like 4 hours, but nothing works.

Send me your paypal, i will send you 10 bucks :D

@Sandeepa-Ceylonsoft
Copy link

@zlAxel No worries pal. Glad I could help.

@Akk2397
Copy link

Akk2397 commented Nov 23, 2023

@Sandeepa-Ceylonsoft I am still facing the issue
In my console it is throwing error
localhost/:1 Access to XMLHttpRequest at 'http://127.0.0.1:8000/api/login' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

and secondly for this in laravel decrypt(encryptedData, unserialize:false);
undefined variable decrypt
is decrypt is a function can u send me the code of laravel to decrypt.

@vikasvyas47
Copy link

by this code i decrypt data which comes from laravel to vuejs

let encryptStrVal = CryptoJS.enc.Base64.parse(encryptStr);
let encryptData = encryptStrVal.toString(CryptoJS.enc.Utf8);
encryptData = JSON.parse(encryptData);

  let iv = CryptoJS.enc.Base64.parse(encryptData.iv);
  
  var decrypted = CryptoJS.AES.decrypt(encryptData.value,  CryptoJS.enc.Base64.parse(encryptionKey), {
        iv : iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });
    
  decrypted = CryptoJS.enc.Utf8.stringify(decrypted); 

now i am trying to decrypt data which post from vuejs to laravel using this process

  let iv = CryptoJS.lib.WordArray.random(16);

let key = CryptoJS.enc.Base64.parse(encryptionKey);

let options = {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
};
let encrypted = CryptoJS.AES.encrypt(JSON.stringify(data), key, options);

encrypted = encrypted.toString();
iv = CryptoJS.enc.Base64.stringify(iv);
let result = {
    iv: iv,
    value: encrypted,
    mac: CryptoJS.HmacSHA256(iv + encrypted, key).toString()
}
result = JSON.stringify(result);
result = CryptoJS.enc.Utf8.parse(result);
let encryptedData = CryptoJS.enc.Base64.stringify(result);

laravel code 
$encryptionKey = env('APP_KEY');
   $encryptedData = $request->input('encryptedData');

   $encryptedData = base64_decode($encryptedData);
   $data  = json_decode($encryptedData, true);

   $iv    = base64_decode($data['iv']);
   $value = $data['value'];
   $mac   = $data['mac'];

   $computedMac = hash_hmac('sha256', $data['iv'] . $data['value'], base64_decode($encryptionKey));

   if (!hash_equals($mac, $computedMac)) 
   {
      return response()->json(['error' => 'MAC verification failed'], 400);
   }
   
  $decryptedValue = Crypt::decrypt($value);
  
  it's not working

@flickervale
Copy link

flickervale commented Jul 11, 2024

I make some adjustment..
I'm using laravel v8.x and vuejs v3.

Assume both APP_KEY in Laravel and Vuejs are match. Do not forget to remove prefix base64: in .env vuejs

At laravel code:

use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Log;

class Helper
{
  public static function encrypt($text)
      {
          if ($text) {
              try {
                  $text = (string)$text;
                  /** set unserialize to false */
                  $encrypted = Crypt::encrypt($text, false);
                  return $encrypted;
              } catch (\Throwable $e) {
                  Log::error("error encrypt ", [$e->getMessage()]);
              }
          }
          return "";
      }
  
   public static function decrypt($text)
      {
          if ($text) {
              try {
                  /** set unserialize to false */
                  $decrypted = Crypt::decrypt($text, false);
                  return $decrypted;
              } catch (\Exception $e) {
                  Log::error("error decrypt ", [$e->getMessage()]);
              }
          }
          return "";
      }
}

Then at vuejs:

import CryptoJS from "crypto-js";

const LaravelEncrypt = function (key) {
    this.key = key;
};

LaravelEncrypt.prototype.decrypt = function (encryptStr) {
    try {
        encryptStr = CryptoJS.enc.Base64.parse(encryptStr);
        let encryptData = encryptStr.toString(CryptoJS.enc.Utf8);
        encryptData = JSON.parse(encryptData);

        let iv = CryptoJS.enc.Base64.parse(encryptData.iv);
        let decrypted = CryptoJS.AES.decrypt(encryptData.value, CryptoJS.enc.Base64.parse(this.key), {
            iv: iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        });

        decrypted = CryptoJS.enc.Utf8.stringify(decrypted);
        return decrypted;
    } catch (error) {
        return null;
    }
};

LaravelEncrypt.prototype.encrypt = function (data) {
    // Generate a random IV
    let iv = CryptoJS.lib.WordArray.random(16);

    // Parse the key into CryptoJS format
    let key = CryptoJS.enc.Base64.parse(this.key);

    // Encryption options
    let options = {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    };

    // Perform AES encryption
    let encrypted = CryptoJS.AES.encrypt(data, key, options);
    encrypted = encrypted.toString(); // Convert encrypted data to string

    // Convert IV to Base64 format
    iv = CryptoJS.enc.Base64.stringify(iv);

    // Calculate HMAC for integrity check
    let mac = CryptoJS.HmacSHA256(iv + encrypted, key).toString();

    // Prepare final result as JSON object
    let result = {
        iv: iv,
        value: encrypted,
        mac: mac
    };

    // Convert result to UTF-8 encoded string and then Base64 format
    result = JSON.stringify(result);
    result = CryptoJS.enc.Utf8.parse(result);
    return CryptoJS.enc.Base64.stringify(result);
};

export default LaravelEncrypt;

You just need to change the key from CryptoJS.enc.Utf8.parse(this.key) to CryptoJS.enc.Base64.parse(this.key) in vuejs.
Also set unserialize to false at decrypt and encrypt function in Laravel.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment