如何在Node.js中使用crypto-js解密Laravel 7.0的加密值?
Hey there! I’ve tackled this exact problem before—decrypting Laravel 7’s encrypted values in Node.js with crypto-js is totally doable once you understand how Laravel handles encryption under the hood. Let’s break it down step by step:
Laravel’s encrypt() method outputs a base64-encoded string that’s actually a JSON object containing three core parts:
iv: The initialization vector (base64-encoded) used for AES-CBC encryptionvalue: The actual encrypted data (base64-encoded)mac: A message authentication code (HMAC-SHA256) to verify the data hasn’t been tampered with
First, add the crypto-js package to your Node.js project via npm:
npm install crypto-js
Grab your Laravel app’s APP_KEY from the .env file. Important: remove the base64: prefix from the key—we’ll need to decode the raw base64 string to get the actual encryption key used by Laravel.
Here’s a complete implementation that handles decryption and includes critical MAC validation to ensure data integrity:
const CryptoJS = require('crypto-js'); // 1. Configure your Laravel APP_KEY (remove "base64:" prefix first) const LARAVEL_APP_KEY = 'your-app-key-without-base64-prefix'; const ENCRYPTION_KEY = CryptoJS.enc.Base64.parse(LARAVEL_APP_KEY); // 2. Helper function to verify data integrity via MAC function verifyDataIntegrity(encryptedData) { const iv = CryptoJS.enc.Base64.parse(encryptedData.iv); const encryptedValue = CryptoJS.enc.Base64.parse(encryptedData.value); // Combine IV and encrypted value bytes const combined = CryptoJS.lib.WordArray.create( iv.words.concat(encryptedValue.words), iv.sigBytes + encryptedValue.sigBytes ); // Compute HMAC-SHA256 using the encryption key const computedMac = CryptoJS.HmacSHA256(combined, ENCRYPTION_KEY).toString(CryptoJS.enc.Hex); // Compare computed MAC with the one from Laravel's encrypted data return computedMac === encryptedData.mac; } // 3. Main decryption function function decryptLaravelEncryptedString(encryptedString) { try { // Decode the base64 string to get the underlying JSON object const decodedBase64 = CryptoJS.enc.Base64.parse(encryptedString).toString(CryptoJS.enc.Utf8); const encryptedData = JSON.parse(decodedBase64); // Validate MAC first to prevent tampered data from being decrypted if (!verifyDataIntegrity(encryptedData)) { throw new Error('Data integrity check failed—encrypted value may have been altered'); } // Parse IV and encrypted value from the data const iv = CryptoJS.enc.Base64.parse(encryptedData.iv); const ciphertext = CryptoJS.enc.Base64.parse(encryptedData.value); // Perform AES-CBC decryption (matches Laravel 7's default encryption settings) const decrypted = CryptoJS.AES.decrypt( { ciphertext: ciphertext }, ENCRYPTION_KEY, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 } ); // Convert decrypted bytes to human-readable plain text return decrypted.toString(CryptoJS.enc.Utf8); } catch (error) { throw new Error(`Decryption failed: ${error.message}`); } }
Use the function with your actual Laravel-encrypted string like this:
// Replace this with your real Laravel encrypted value const laravelEncryptedValue = 'eyJpdiI6IlRZd...'; try { const plainText = decryptLaravelEncryptedString(laravelEncryptedValue); console.log('Decrypted result:', plainText); } catch (err) { console.error('Error:', err.message); }
- Laravel 7 Defaults: Laravel uses AES-256-CBC with PKCS7 padding by default—don’t modify these settings in the crypto-js config unless you’ve changed Laravel’s encryption setup.
- APP_KEY Handling: Forgetting to remove the
base64:prefix will cause decryption to fail immediately. - MAC Validation: Skipping this step leaves your app vulnerable to tampered data—always include it in production code.
内容的提问来源于stack exchange,提问作者Denny Rustandi

