hungneox
hungneox

Reputation: 9829

Laravel 5 - Decrypt Crypt::encrypt in Javascript

I'm using Crypt::encrypt to encrypt my data and feed to Javascript code. How can I decrypt the data in Javascript?

Upvotes: 7

Views: 17161

Answers (4)

NKol
NKol

Reputation: 751

The answers above didn't work for me. So I tried to encrypt the string "1234" on Laravel 8 and then decrypt it on Node.js.

My actual use case is that we set our OAuth2 access token as an encrypted cookie on Laravel 8. Then our client sends HTTP-requests to a Node.js backend (microservice architecture). To validate the JWT token, the Node.js backend needs to decrypt the (Laravel)-encrypted access token first.

ENCRYPT (Laravel 8):

Open any Controller and add the following code in a function:

use Illuminate\Support\Facades\Crypt;

return Crypt::encrypt("1234");

If you now open the route, which is linked to the controller method, you get the encrypted string of "1234".

DECRYPT (Node.js)

Please make sure to install crypto-js first (https://github.com/brix/crypto-js).

Do the following steps before you run the code:

  1. Replace "your_string_to_decrypt" by the encrypted "1234" string (you retrieved from Laravel before)

  2. Replace "your_laravel_app_key" with your Laravel APP_KEY from your .env (remove the "base64:" part !)

  3. Important to know: Your encryption cipher-method in Laravel is defined in config/app.php. The default is "AES-256-CBC". Crypto-Js automatically selects the right AES-cipher depending on the length of your specified key. After removing "base64:" your key should have 44 characters for using "AES-256-CBC". (https://security.stackexchange.com/questions/45318/how-long-in-letters-are-encryption-keys-for-aes#:~:text=An%20AES%20128%2Dbit%20key,hexadecimal%20string%20with%2032%20characters.)

CryptoJS supports AES-128, AES-192, and AES-256. It will pick the variant by the size of the key you pass in. If you use a passphrase, then it will generate a 256-bit key. https://cryptojs.gitbook.io/docs/#ciphers

import CryptoJS from 'crypto-js';

let payload = "your_string_to_decrypt"
let key = "your_laravel_app_key"

let encryptStr = CryptoJS.enc.Base64.parse(payload);
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.Base64.parse(key), {
    iv : iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
});
decrypted = CryptoJS.enc.Utf8.stringify(decrypted);

console.log(decrypted)

Finally you are done and the Node.js log shows "1234".

(Of course this is not the best code, but it shows the functionality).

References:

Node.js code: https://gist.github.com/huzemin/e8d7a904cec55d4d7635c9322f143c42

Upvotes: 1

SirCumz
SirCumz

Reputation: 171

CryptoJs and Laravel 6 & 7.x

Place a Mix variable inside .env file

MIX_APP_KEY=${APP_KEY}

See: https://laravel.com/docs/7.x/mix#environment-variables

In /resources/assets/js/app.js add:

const CryptoJS = require("crypto-js");

window.decrypt = (encrypted) => {
    let key = process.env.MIX_APP_KEY.substr(7);
    var encrypted_json = JSON.parse(atob(encrypted));
    return CryptoJS.AES.decrypt(encrypted_json.value, CryptoJS.enc.Base64.parse(key), {
        iv : CryptoJS.enc.Base64.parse(encrypted_json.iv)
    }).toString(CryptoJS.enc.Utf8);
};

And finally somewhere in your script you can decrypt like so:

console.log(decrypt(encrypted_text)); 

Upvotes: 4

Pablo Salazar
Pablo Salazar

Reputation: 957

I SOLVE THIS:

I'm using Laravel Framework 5.7.28 and i want to decrypt some users passwords in my node.js application

For Decrypt in my Js file i include CryptoJS and Base64 JS

Here is the code:

$key is the APP_KEY that you have in your .env file
$encrypted is what you encrypt with the Crypt::encrypt in laravel

var CryptoJS = require("crypto-js");
var Base64 = require('js-base64').Base64;


var encrypted = '{{ $encrypted }}';
var key = "{{ $key }}";

var encrypted_json = JSON.parse(Base64.decode(encrypted));


// Now I try to decrypt it.
var decrypted = CryptoJS.AES.decrypt(encrypted_json.value, CryptoJS.enc.Base64.parse(key), {
       iv : CryptoJS.enc.Base64.parse(encrypted_json.iv)
});

console.log(decrypted.toString(CryptoJS.enc.Utf8));

Upvotes: 2

Wubni Jameel
Wubni Jameel

Reputation: 91

Using laravel 5.1 and CryptoJS which can be found at (https://code.google.com/p/crypto-js/).

in .env set:

  1. APP_KEY=uberkeythatrocks

in config/app.php set:

  1. 'cipher' => 'AES-256-CBC'

in MyController.php:

  1. $mySecret = "Something I wanna hide from them";

  2. $encrypted = Crypt::encrypt($mySecret);

in index.js:

  1. var key = "uberkeythatrocks";

  2. var decrypted = CryptoJS.AES.decrypt(encrypted, key);

  3. var readable = decrypted.toString(CryptoJS.enc.Utf8);

IMPORTANT: The 'key' in PHP must be the same with 'key' in JS and the 'cipher' in PHP must be the same in JS however, CryptoJS will automatically select either AES-128-CBC or AES-256-CBC depending on the length of your 'key'. Although laravel 5.1 default 'cipher' is AES-256-CBC so I would suggest you get your 'key' from .env file to use in JS.

To change or generate a new 'key' from Laravel

  1. C:/mylaravel> php artisan key:generate [enter]

To use AES-128-CBC

  1. Edit config/app.php and set 'cipher' => 'AES-128-CBC'

then

  1. C:/mylaravel> php artisan key:generate [enter]

NOTE that the change of 'key' will mean that an existing user account login password will not work unless you delete the user and then create new.

HOPE THIS HELPS! :)

Upvotes: 9

Related Questions