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

