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
相关产品推荐
相关产品推荐

