Skip to content

Instantly share code, notes, and snippets.

@huzemin
Created December 3, 2019 06:47
Show Gist options
  • Star 23 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • 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;
@tim-reynolds-thegrommet

So I tried using this, and it was almost perfect. I only needed the encrypt. I had to change line 23 from
CryptoJS.enc.Utf8.parse(this.key)
to
CryptoJS.enc.Base64.parse(this.key)

After that I was able to decrypt the encrypted data in Laravel. Note, I was passing in the key as a string exactly as it appears in my .env so if you intended it to be passed a different way then ignore me :)

Thank you again.

@careless10
Copy link

careless10 commented Aug 10, 2020

Thank you,
and thank you @tim-reynolds-thegrommet , for me to get this working i had to also change the line 12 that has also the same code as you mentioned,

CryptoJS.enc.Utf8.parse(this.key)

to

CryptoJS.enc.Base64.parse(this.key)

so for anyone who can't figure it out its line 12 and line 23.

@vijaysapp
Copy link

vijaysapp commented Aug 17, 2020

hi @tim-reynolds-thegrommet & @careless10 , im getting error when i tried to pass this encrypted data to Laravel 5.5 for further decryption. kindly give some idea

Illuminate \ Contracts \ Encryption \ DecryptException
The MAC is invalid.

@naushrambo
Copy link

naushrambo commented Sep 2, 2020

hi @tim-reynolds-thegrommet & @careless10 , im getting error when i tried to pass this encrypted data to Laravel 5.5 for further decryption. kindly give some idea

Illuminate \ Contracts \ Encryption \ DecryptException
The MAC is invalid.

@huzemin @tim-reynolds-thegrommet & @careless10 & @vijaysapp Me too getting same error in Laravel 5.4 too. please help.

@naushrambo
Copy link

@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