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

React Native中CryptoJS AES解密函数返回空串问题排查

解决React Native中CryptoJS AES解密返回空字符串的问题

问题根源

你的代码和PHP端加密逻辑存在几个关键不匹配:

  • 密钥处理:PHP用hex2bin($KEY)将十六进制密钥转为原始二进制字节,而你之前错误地将解析后的密钥转成字符串传入CryptoJS,导致密钥推导逻辑不符
  • 数据拼接/解析:PHP直接拼接二进制IV和密文后base64编码,而你之前把IV和密文转成字符串拼接,解密时又转成ascii解析,破坏了二进制数据
  • 密文获取:CryptoJS的AES.encrypt返回的是CipherParams对象,直接转字符串会得到base64编码的密文(带格式),而不是原始二进制密文

修正后的加密解密函数

加密函数

import { Buffer } from 'buffer';
import { KEY } from '../constants/Constants';
import CryptoJS from 'react-native-crypto-js';

const CryptoJSAesEncrypt = (text) => {
    // 解析十六进制密钥为WordArray(对应PHP的hex2bin)
    const key = CryptoJS.enc.Hex.parse(KEY);
    // 生成16字节随机IV
    const iv = CryptoJS.lib.WordArray.random(16);
    // 加密,获取原始密文(ciphertext是WordArray格式的二进制密文)
    const encryptedData = CryptoJS.AES.encrypt(text, key, {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7 // PHP默认用Pkcs7填充,和CryptoJS默认一致
    }).ciphertext;
    // 拼接IV和密文为一个WordArray
    const combined = iv.concat(encryptedData);
    // 转base64返回(对应PHP的base64_encode)
    return combined.toString(CryptoJS.enc.Base64);
};

解密函数

const CryptoJSAesDecrypt = (encrypted) => {
    // 解析十六进制密钥为WordArray
    const key = CryptoJS.enc.Hex.parse(KEY);
    // 将base64编码的字符串转成WordArray
    const combined = CryptoJS.enc.Base64.parse(encrypted);
    // 截取前16字节作为IV
    const iv = combined.clone();
    iv.sigBytes = 16;
    iv.words = iv.words.slice(0, 4); // 每个Word是4字节,16字节就是4个Word
    // 截取剩下的作为密文
    const encryptedData = combined.clone();
    encryptedData.sigBytes = combined.sigBytes - 16;
    encryptedData.words = encryptedData.words.slice(4);
    // 解密
    const decrypted = CryptoJS.AES.decrypt({ ciphertext: encryptedData }, key, {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });
    // 转成UTF8字符串返回
    return decrypted.toString(CryptoJS.enc.Utf8);
};

测试验证

用你的测试文本YES!测试:

const text = 'YES!';
const encrypted = CryptoJSAesEncrypt(text);
const decrypted = CryptoJSAesDecrypt(encrypted);
console.log('原文:', text); // 原文: YES!
console.log('加密后:', encrypted);
console.log('解密后:', decrypted); // 解密后: YES!

关键匹配点说明

  • 密钥:PHP的hex2bin($KEY)对应CryptoJS的CryptoJS.enc.Hex.parse(KEY),直接使用二进制密钥,避免字符串转码错误
  • IV和密文拼接:PHP直接拼接二进制数据,CryptoJS用WordArray.concat实现相同逻辑
  • 密文处理:PHP返回的是原始加密字节,CryptoJS通过ciphertext获取原始密文,而非格式化后的字符串
  • 填充和模式:PHP的openssl_encrypt默认用PKCS7填充、CBC模式,和CryptoJS默认配置一致,无需额外修改

内容的提问来源于stack exchange,提问作者Mombre Enpellido

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 13:43:27