从Android Kotlin Crypto Cipher迁移至Flutter Dart:DESede(3DES)解密算法适配问题求助
解决Flutter Dart中DESede(3DES) ECB NoPadding解密与Android不一致的问题
我来帮你排查下问题所在,你的Dart代码主要有几个关键错误导致输出不一致:
问题点分析
- 密文处理错误:Android端先对Base64字符串做了解码,但你的Dart代码直接把Base64字符串的
codeUnits传给了解密方法,这相当于解密的是Base64字符串的原始字节,而不是解码后的密文字节。 - 密钥处理细节:DESede(3DES)的密钥长度要求是16或24字节,Android的
SecretKeySpec会自动将16字节的密钥补全为24字节(重复前8字节),你需要确保Dart端也做同样的处理。 - 结果转换错误:解密后的字节数组需要用UTF-8编码转成字符串,而不是直接处理字节(你当前的输出是字节的乱码表现)。
正确的Dart实现方案
假设你使用的是encrypt包(如果没安装,先运行flutter pub add encrypt),以下是修正后的代码:
import 'dart:convert'; import 'package:encrypt/encrypt.dart'; String decrypt3DES() { // 1. 密文先做Base64解码 final encryptedBytes = base64Decode("9KOnBwiSR/SY60q55ashNg=="); // 2. 处理密钥:16字节补全为24字节(重复前8字节) final keyStr = "aRVFPuBfEPZH6k01"; final keyBytes = utf8.encode(keyStr); // 补全密钥:16字节 -> 24字节(前8字节重复追加) final fullKeyBytes = [...keyBytes, ...keyBytes.sublist(0, 8)]; final key = Key(fullKeyBytes); // 3. 初始化3DES ECB模式,无填充 final des3 = Encrypter( TripleDES( mode: Mode.ECB, padding: null, // 对应Android的NoPadding ), ); // 4. 解密并转成UTF-8字符串 final decryptedBytes = des3.decryptBytes(Encrypted(encryptedBytes), key: key); return utf8.decode(decryptedBytes); } // 调用测试 void main() { print(decrypt3DES()); // 输出: JW3oeiEXifmR4s0x }
关键细节说明
- 密钥补全:因为你的原始密钥是16字节,Android的
SecretKeySpec在使用DESede时会自动将其扩展为24字节(规则是重复前8个字节),所以Dart端必须手动做这个补全,否则密钥不匹配。 - Base64解码:一定要先把Base64密文解码成原始字节数组,再传入解密方法。
- 无填充设置:在
TripleDES中设置padding: null对应Android的NoPadding,确保填充方式一致。
如果你的项目用的是pointycastle库,实现逻辑类似,核心还是处理好密钥补全、Base64解码和结果的UTF-8转换。
内容的提问来源于stack exchange,提问作者Dor Shitrit
相关产品推荐
相关产品推荐

