Laravel与React间AES-256-CBC加解密报错:解密消息为空
Laravel后端加密与React前端解密报错:"Decryption error: Empty message"
问题描述
在Laravel后端对接口响应加密,React前端解密时出现以下错误:
"Decrypted Message: Decryption error: Empty message"
Laravel端代码(文件路径:routes/web.php)
<?php use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Crypt; use Illuminate\Contracts\Encryption\DecryptException; header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS'); header('Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization'); Route::get('/', function () { $message = 'Secret message'; $encryptionKey = 'dummykey12345678'; // 替换为有效的AES密钥 $iv = '1234567812345678'; // 校验密钥长度合法性 if (strlen($encryptionKey) !== 16 && strlen($encryptionKey) !== 24 && strlen($encryptionKey) !== 32) { return response()->json(['error' => 'Invalid AES key']); } $encryptedMessage = openssl_encrypt($message, 'AES-256-CBC', $encryptionKey, 0, $iv); return response()->json(['encryptedMessage' => $encryptedMessage, 'iv' => $iv]); });
接口输出(地址:http://192.168.8.183:8000/)
{"encryptedMessage":"d06MJ4mj2lPLfzEb3W/vcw==","iv":"aaaaaaaaaaaaaaaa"}
React.js端代码(文件路径:src/App.js)
import React, { useEffect, useState } from 'react'; import CryptoJS from 'crypto-js'; function App() { const [decryptedMessage, setDecryptedMessage] = useState(''); useEffect(() => { // 调用接口获取加密消息和IV fetch('http://192.168.8.183:8000/') // 替换为实际接口地址 .then((response) => response.json()) .then((data) => { const { encryptedMessage, iv } = data; // 替换为16、24或32字节长度的有效AES密钥 const encryptionKey = CryptoJS.enc.Utf8.parse('dummykey12345678'); try { // 解密消息 const decryptedBytes = CryptoJS.AES.decrypt(encryptedMessage, encryptionKey, { iv: CryptoJS.enc.Hex.parse(iv) }); // 将解密后的字节转换为明文 const decryptedMessage = decryptedBytes.toString(CryptoJS.enc.Utf8); // 更新解密消息状态 if (decryptedMessage) { setDecryptedMessage(decryptedMessage); } else { setDecryptedMessage('Decryption error: Empty message'); } } catch (error) { console.error('Decryption error:', error); setDecryptedMessage('Decryption error: ' + error.message); } }) .catch((error) => { console.error('Error:', error); }); }, []); return ( <div> <h1>Decrypted Message: {decryptedMessage}</h1> </div> ); } export default App;
排查解决方向
- IV解析格式不匹配:Laravel端的IV是UTF-8字符串(如
aaaaaaaaaaaaaaaa),但React端用CryptoJS.enc.Hex.parse(iv)解析——Hex解析要求输入为十六进制字符,普通UTF-8字符串会导致IV无效。需改为CryptoJS.enc.Utf8.parse(iv)。 - 密钥与加密算法不匹配:Laravel使用
AES-256-CBC,要求密钥长度为32字节,但当前密钥dummykey12345678仅16字节,实际会降级为AES-128。需统一算法:要么Laravel改用AES-128-CBC,要么将密钥调整为32字节的有效字符串。 - 加密输出编码验证:Laravel中
openssl_encrypt默认输出Base64编码,CryptoJS的AES.decrypt可直接处理该格式,但需确保接口输出没有多余转义(当前输出中的\/是JSON自动转义,解析后会还原为/,此部分无问题)。 - 填充方式一致性:Laravel的
openssl_encrypt默认使用PKCS#7填充,CryptoJS也默认采用该方式,若两端未手动修改填充配置,此部分无需调整。
内容的提问来源于stack exchange,提问作者Naoum007
相关产品推荐
相关产品推荐

