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

从React Native迁移至Flutter/Dart时,使用encrypt库解密AES-CTR数据出现乱码的问题排查

从React Native到Flutter的AES-CTR解密迁移问题解决方案

你遇到的乱码问题主要是因为密文的解码方式和React Native的CryptoJS逻辑不一致,另外还有几个细节需要精准对齐,以下是具体的修正步骤:

核心错误:密文解析方式不对

在React Native的代码里,CryptoJS.AES.decrypt(cipher, ...)默认会把传入的cipher字符串当作Base64编码来解码;但你在Flutter中用了Encrypted.fromUtf8(cipher),这会把密文当成普通UTF8字符串处理,直接导致解密失败得到乱码。

修正后的完整Flutter代码

import 'package:encrypt/encrypt.dart';

String decryptSessionKey(String randomKey, String cipher) {
  // 对齐CryptoJS的NoPadding配置
  final encrypter = Encrypter(AES(
    Key.fromUtf8(randomKey),
    mode: AESMode.ctr,
    padding: null, // 和CryptoJS.pad.NoPadding对应
  ));
  
  // 截取randomKey前16个字符作为IV,和RN逻辑完全一致
  final iv = IV.fromUtf8(randomKey.substring(0, 16));
  
  // 关键修正:密文是Base64格式,改用fromBase64解析
  final encryptedData = Encrypted.fromBase64(cipher);
  
  final decrypted = encrypter.decrypt(encryptedData, iv: iv);
  return decrypted;
}

其他需要确认的对齐点

我帮你核对了两边的逻辑,确保其他参数都匹配:

  • IV长度:CTR模式下IV长度要求是16字节(AES块大小),你已经正确截取了randomKey前16个字符,这部分没问题。
  • 密钥长度:你的randomKey是32个UTF8字符,对应256位密钥,两边都用fromUtf8生成密钥,逻辑一致。
  • Padding设置:Flutter的encrypt库中padding: null正好对应CryptoJS的NoPadding,配置正确。

用你提供的测试值验证:

  • randomKey: 0QaOUmxpugtnRUTZ6yOSxQeZq47Akiqf
  • cipher: piMgUF2ISUl/g7ns2/gZyaWQm6Rdv7x500GD7lMLYxhy14Tg+Bizibvz

修正后的代码应该能得到和React Native完全一致的结果:54387c3b38150d2a7a1c545167736e701629382648

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 05:32:43