如何用 Laravel 加密的加密程序解密数据?
原标题:How to decrypt data encrypted using crypto-js in laravel?
I have this bit of code in my js :
export const encrypt = (data, key) => {
const encrypted = CryptoJS.AES.encrypt(
JSON.stringify(data),
key
).toString();
return encrypted;
};
but when i decrypt it in my laravel backend :
Route::post( /decrypt , function (Request $request) {
try{
$encrypted = $request->input("data");
Crypt::decrypt($encrypted);
}
catch(DecryptException $e) {
dd("error", $e);
}
});
this gives me the DecryptException "The payload is invalid"
问题回答
It looks like you re encountering an issue because the encryption methods and libraries you re using in JavaScript and Laravel are not compatible by default. CryptoJS.AES.encrypt and Crypt::decrypt in Laravel use different default configurations and algorithms. Here are a few points to ensure compatibility between your JavaScript and Laravel encryption methods:
Consistent Encryption Parameters: Ensure that both JavaScript and Laravel use the same encryption parameters (algorithm, mode, padding, etc.). By default, CryptoJS.AES.encrypt uses CBC mode and PKCS7 padding. Laravel s Crypt facade uses AES-256-CBC mode and PKCS7 padding as well, but it requires a specific key size and configuration.
Ensure that the key used in JavaScript matches the key used in Laravel and that you properly manage the IV (Initialization Vector). The CryptoJS.AES.encrypt method may also require specifying an IV. In Laravel, the Crypt facade handles IV internally, but in a custom implementation, you ll need to manage IV manually.
Encoding: Make sure that the data is properly encoded and decoded between the systems. CryptoJS outputs Base64-encoded strings, and Laravel expects Base64 encoding as well.
I think the below should help:
export const encrypt = (data, key) => {
// Ensure your key is 32 bytes for AES-256
const keySize = 256 / 32;
const keyHex = CryptoJS.enc.Hex.parse(key);
const iv = CryptoJS.lib.WordArray.random(16); // Random 16 bytes IV
const encrypted = CryptoJS.AES.encrypt(
JSON.stringify(data),
keyHex,
{ iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }
);
// Encode both the IV and the encrypted data
return `${iv.toString(CryptoJS.enc.Base64)}:${encrypted.toString()}`;
};
Laravel Decryption
Route::post( /decrypt , function (Request $request) {
try {
// Extract the IV and encrypted data
$data = $request->input( data );
list($iv, $encrypted) = explode( : , $data, 2);
// Decode the Base64 encoded values
$iv = base64_decode($iv);
$encrypted = base64_decode($encrypted);
// Your key should be 32 bytes for AES-256
$key = env( AES_KEY ); // Ensure this key matches the one used in JavaScript
// Decrypt using openssl
$decrypted = openssl_decrypt(
$encrypted,
aes-256-cbc ,
$key,
OPENSSL_RAW_DATA,
$iv
);
return response()->json([ data => json_decode($decrypted, true)]);
} catch (DecryptException $e) {
return response()->json([ error => Decryption failed ], 400);
}
});
Well... the encryption world is extremely tricky, so never take anything for granted. While encrypting/decrypting with the same tool is somewhat trivial, doing the same across different systems may reveal very troublesome.
Here, assuming all the elements are in place (correct install, correct config...!), the problem might lay in the data or the key.
Key
As pointed out by @Kris, you should check if "the key is the same in both sides". That might seem obvious at first glance... but it s not really so.
In effect, before encrypting/decrypting, CryptoJS first checks if "key" is a real key or a plaintext password (called passphrase). If the latter is the case, then it converts the plaintext password into a key, and then processes the data. Again... what type of conversion? To a key of what length? It all depends in the configuration you have, and the defaults of your version. Usually, the default key size is 256.
Now, I don t see any password setting in your backend example, but you should check if it is handling the key in the same exact way as CryptoJS is doing it. If you have control, you could try to replicate, in the backend, CryptoJS s exact behavior with the key. But handling the conversion yourself might be a real timesaver, providing CryptoJS with a real key that it s not going to try to process.
Data
Encrypted data is typically binary, and not suitable for transport. There are many forms to transport data safely, and one of the more widely used is BASE64. This is actually what CryptoJS converts the data to, when using toString(), like you do.
Now, you have to check that your backend is expecting this format, and deals with it correctly, both the interface and the decryption routine. For instance, if Crypt::decrypt() is expecting binary data, you should first BASE64 decode the received data.
相关问题
selected text in iframe
How to get a selected text inside a iframe.
I my page i m having a iframe which is editable true.
So how can i get the selected text in that iframe.
How to fire event handlers on the link using javascript
I would like to click a link in my page using javascript. I would like to Fire event handlers on the link without navigating. How can this be done? This has to work both in firefox and Internet ...
How to Add script codes before the </body> tag ASP.NET
Heres the problem,
In Masterpage, the google analytics code were pasted before the end of body tag.
In ASPX page, I need to generate a script (google addItem tracker) using codebehind ClientScript ...
Clipboard access using Javascript - sans Flash?
Is there a reliable way to access the client machine s clipboard using Javascript? I continue to run into permissions issues when attempting to do this. How does Google Docs do this? Do they use ...
javascript debugging question
I have a large javascript which I didn t write but I need to use it and I m slowely going trough it trying to figure out what does it do and how, I m using alert to print out what it does but now I ...
Displaying a Multidimensional Array in a Bar Graph (in JavaScript)?
Is it possible for someone to give me a few pointers on how to display a multidimensional array in the form of a bar graph?
The array is multidimensional, with three elements in each part - and the ...
Is it possible to reload a form after an input type="file" changes?
Is it possible to reload a form after file-input change?
I have a form where the user can chose an image for upload. I also have a php script which displays that image resized.
I only wonder if it ...
Parsing date like twitter
I ve made a little forum and
I want parse the date on newest posts like twitter, you know "posted 40 minutes ago ","posted 1 hour ago"...
What s the best way ?
Thanx.