You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React Native CryptoJS AES加密:Android Release构建解密失败问题

解决React Native Android Release构建下AES加解密不兼容问题

你遇到的这个问题其实是React Native Release构建的代码优化导致的加密一致性问题——Debug模式下react-native-crypto-js的加密逻辑和Release环境存在细微差异,最终导致服务端无法解密Release包生成的密文。下面是具体的原因分析和修正方案:

问题根源

在Android Release构建中,RN会对JavaScript代码进行混淆、压缩和死代码消除,这可能导致react-native-crypto-js对密钥、IV的处理逻辑和Debug环境不一致。你当前的代码直接使用字符串作为密钥,而CryptoJS在不同环境下对字符串密钥的自动解析规则可能发生变化,最终导致加解密使用的实际密钥不匹配。

修正后的完整代码

React Native 端加密代码

import CryptoJS from "react-native-crypto-js";

export const encryptValue = (text) => {
  try {
    // 把字符串密钥统一转换为WordArray,避免环境差异导致的解析不同
    const key = CryptoJS.enc.Utf8.parse('J4f9eO8ayjjEtamRBxSSmsDqXBele1zl');
    // 生成16字节(128位)的IV,明确长度避免歧义
    const iv = CryptoJS.lib.WordArray.random(16);
    const encrypted = CryptoJS.AES.encrypt(
      text,
      key,
      { 
        iv: iv,
        mode: CryptoJS.mode.CBC, // 显式指定加密模式,使用默认的CBC但明确写出更稳妥
        padding: CryptoJS.pad.Pkcs7 // 明确填充方式,避免环境默认值差异
      });
    
    // 统一使用十六进制格式传输IV,保证解析一致性
    return { 
      iv: iv.toString(CryptoJS.enc.Hex), 
      encryptedData: encrypted.toString() 
    };
  } catch (error) {
    console.error('加密失败:', error);
    throw error; // 抛出错误让上层处理,而不是默默吞掉
  }
}

Node.js 服务端解密代码

const CryptoJS = require('crypto-js');

export const decrypt = (data) => {
  try {
    // 和RN端保持一致,将密钥转换为WordArray
    const key = CryptoJS.enc.Utf8.parse("J4f9eO8ayjjEtamRBxSSmsDqXBele1zl");
    // 把前端传来的十六进制IV转换回WordArray
    const iv = CryptoJS.enc.Hex.parse(data.iv);
    const decrypted = CryptoJS.AES.decrypt(
      data.encryptedData,
      key,
      { 
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
      }).toString(CryptoJS.enc.Utf8);
    
    console.log('解密结果:', decrypted);
    return decrypted;
  } catch (err) {
    console.error('解密失败:', err);
    throw err;
  }
}

关键修改说明

  • 统一密钥处理:将字符串密钥转换为WordArray,彻底避免不同环境下CryptoJS对字符串密钥的自动解析差异
  • 显式指定加解密参数:明确写出加密模式和填充方式,防止不同环境下默认值不一致
  • IV编码标准化:使用十六进制格式传输IV,替代原来的默认toString(),保证两端解析规则完全一致
  • 优化错误处理:抛出错误而非仅打印日志,方便上层代码捕获并处理异常情况

额外建议

  • 确保React Native端的react-native-crypto-js版本和服务端的crypto-js版本完全一致,版本差异也可能导致加解密不兼容
  • 检查Android Release构建的Gradle配置,避免禁用了CryptoJS依赖的某些JavaScript特性,导致功能异常

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

火山引擎 最新活动