You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 11:24:49