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;
@vesterliandrei
Copy link

Hi @huzemin

Getting same error 'The MAC is invalid.' and it doesn't matter if it's "Utf8" or "Base64". Tried both cases. Context: laravel 7.x.
Any ideas, suggestions what can i do with this? I've spend a few days in order to solve this issue but i can't afford a result.

Regards,
Andrei

@vijaysapp
Copy link

vijaysapp commented Dec 3, 2020 via email

@vesterliandrei
Copy link

Hey @vijaysapp

Can you put the js code you used for encryption? I mean, with utf8 or base64...Just in case. Thx a lot!!

@vijaysapp
Copy link

vijaysapp commented Dec 4, 2020 via email

@vesterliandrei
Copy link

Hello @vijaysapp

Huge thx to you bro!!! You made my day!! It worked!!

@johnsage25
Copy link

Thanks

@dev070607
Copy link

dev070607 commented Apr 10, 2023

@vijaysapp I have to remove base64 in the js app but I can't solve this please help.

I have Getting the same error 'The MAC is invalid.' it doesn't matter if it's "Utf8" or "Base64". Tried both cases. Context: laravel 9.x.

just used the utf8 code. but we should remove the base64: from key value[copy laravel app key & remove base64: in JS app]. thats all

On Fri, Dec 4, 2020 at 12:17 AM Vesterli Andrei @.> wrote: @.* commented on this gist. ------------------------------ Hey @vijaysapp https://github.com/vijaysapp Can you put the js code you used for encryption? I mean, with utf8 or base64...Just in case. Thx a lot!! — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://gist.github.com/e8d7a904cec55d4d7635c9322f143c42#gistcomment-3549304, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQDVWPQXODRSE7FCR7M5HFDSS7MMJANCNFSM4ODAPYHQ .
-- thanks & regards Vijayaragavan Project Manager vijay@annsys.com vijay@annsys.com http://annsys.com/ http://annsys.com/ * http://annsys.com/*

@Sandeepa-Ceylonsoft
Copy link

Sandeepa-Ceylonsoft commented May 26, 2023

@dev070607

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);

@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

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