VueJS使用CryptoJS解密Laravel加密数据时出现类型错误
Laravel加密数据在Vue.js中解密失败的解决方法
问题场景
后端用Laravel的Crypt::encryptString加密数据存入数据库,代码如下:
$message = new WA_Message; $message->content = Crypt::encryptString($received_message); $message->is_business_message = false; $message->conversation_id = $conversation->id; $message->save();
前端Vue.js调用解密时触发错误:
Decryption failed TypeError: Cannot read properties of undefined (reading '0') at Object.xorBlock (crypto-js.js?v=3aa22fc9:2402:41)
前端解密代码(已将Laravel APP_KEY中base64:后的部分存入环境变量):
decryptedMessage() { try { const decrypted = CryptoJS.AES.decrypt(this.message.content, CryptoJS.enc.Base64.parse(import.meta.env.VITE_LARAVEL_APP_KEY)); const stringDecrypted = decrypted.toString(CryptoJS.enc.Utf8); return stringDecrypted; } catch (error) { console.error('Decryption failed', error); return ''; } },
相关测试数据:
- 加密原文:
bzbz 🐝 - 密文:
eyJpdiI6Im94UU5zZ1hLQk5ySkw5Z21lZnExYVE9PSIsInZhbHVlIjoiK1RTOFNEeXY5Q0U0Slh2ZmpUUEMrZz09IiwibWFjIjoiYTM1NzVkNjg2MDliZDI0MDUwNDljMzM5OTlhNDNjNWVkMTI1NmIwNTA4YTI2YzA2NWU4MmZjYzgzMjAxMGYyMCIsInRhZyI6IiJ9 - Laravel APP_KEY:
base64:G3EfLG42xzqWAH1PuoZ72mUTJ1bC8EJMzx+1jqa7/m0=
问题原因
Laravel的Crypt::encryptString生成的不是纯AES密文,而是包含初始化向量(iv)、加密内容(value)、**消息认证码(mac)**的JSON字符串,且整个结构经过了Base64编码。直接把这个字符串传给CryptoJS解密,会因格式不匹配导致报错。
解决方法
修改前端解密逻辑,先解析Laravel的加密结构,再按AES-CBC模式解密(Laravel默认使用AES-256-CBC算法):
decryptedMessage() { try { // 1. 解码Base64密文,解析为JSON对象 const encryptedPayload = JSON.parse(atob(this.message.content)); // 2. 处理密钥、IV和加密内容 const key = CryptoJS.enc.Base64.parse(import.meta.env.VITE_LARAVEL_APP_KEY); const iv = CryptoJS.enc.Base64.parse(encryptedPayload.iv); const ciphertext = CryptoJS.enc.Base64.parse(encryptedPayload.value); // 3. 使用AES-CBC模式解密,配合Pkcs7填充 const decrypted = CryptoJS.AES.decrypt( { ciphertext: ciphertext }, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 } ); return decrypted.toString(CryptoJS.enc.Utf8); } catch (error) { console.error('Decryption failed', error); return ''; } },
核心要点
- 必须先将密文通过
atob解码,再解析成JSON对象,提取其中的iv和value字段 - Laravel默认采用CBC加密模式和Pkcs7填充,解密时必须明确指定这两个参数
- 解密时要把加密内容包装成
{ ciphertext: ... }的格式传给CryptoJS
内容的提问来源于stack exchange,提问作者AllAboutCake
相关产品推荐
相关产品推荐

