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

如何在encrypt.dart中向AES传递List<int>类型的密钥与IV

使用encrypt.dart处理AES解密的问题

我在尝试用encrypt.dart解密AES加密字符串,当前遇到的问题:我已经获取到List类型的密钥(Key)和初始向量(IV),但不知道如何正确传递给解密器。解密器要求密钥为32字节、IV为16字节,但将myKey或myIV转换为十六进制字符串或普通字符串时,长度会翻倍,试过转十六进制也没能解决问题。

相关转换代码示例:

List<int> intList = [189, 249, 66, 29, 132, 72, 230, 0, 235, 175, 236, 175, 246, 114, 21, 20, 79, 4, 174, 195, 121, 156, 172, 10, 50, 64, 94, 96, 112, 85, 204, 149];
String hexString = utf8.decode(intList);
hexString = hexString.runes.map((int rune) => rune.toRadixString(16).padLeft(2, '0').toUpperCase()).join();

核心困惑的代码片段:

List<int> myKey  = [84, 124, 176, 174, 139, 253, 34, 86, 205, 149, 187, 232, 133, 67, 56, 212, 180, 63, 73, 222, 33, 183, 190, 41, 62, 23, 94, 233, 133, 46, 162, 219];
List<int> myIV  = [183, 104, 193, 48, 247, 178, 239, 48, 249, 41, 56, 33, 255, 150, 74, 110];

// 错误尝试:fromUtf8需要传入字符串,而非List<int>
final key = enc.Key.fromUtf8(myKey); // 需要32字节
final iv = enc.IV.fromUtf8(myIV); // 需要16字节

// Encryption
String kelime = 'The quick brown fox jumps over the lazy dog';
final encrypter = enc.Encrypter(enc.AES(key, mode: enc.AESMode.ctr, padding: null));
final encrypted = encrypter.encrypt(kelime, iv: iv);
final ciphertext = encrypted.base64;
print(ciphertext);

// Decryption
final decrypter = enc.Encrypter(enc.AES(key, mode: enc.AESMode.ctr, padding: null));
final decrypted = decrypter.decryptBytes(enc.Encrypted.fromBase64(ciphertext), iv: iv);
final decryptedData = utf8.decode(decrypted);
print(decryptedData);

解决方法

你不需要把List转换成字符串,encrypt.dart提供了直接从字节列表创建Key和IV的方法:Key.fromList()和IV.fromList()。你的myKey已经是32字节的int列表,myIV是16字节的int列表,直接用这两个方法就能生成符合要求的密钥和向量,完全不需要额外转换。

修改后的正确代码:

import 'package:encrypt/encrypt.dart' as enc;

void main() {
  List<int> myKey  = [84, 124, 176, 174, 139, 253, 34, 86, 205, 149, 187, 232, 133, 67, 56, 212, 180, 63, 73, 222, 33, 183, 190, 41, 62, 23, 94, 233, 133, 46, 162, 219];
  List<int> myIV  = [183, 104, 193, 48, 247, 178, 239, 48, 249, 41, 56, 33, 255, 150, 74, 110];

  // 直接从List<int>创建Key和IV
  final key = enc.Key.fromList(myKey);
  final iv = enc.IV.fromList(myIV);

  // 加密
  String kelime = 'The quick brown fox jumps over the lazy dog';
  final encrypter = enc.Encrypter(enc.AES(key, mode: enc.AESMode.ctr, padding: null));
  final encrypted = encrypter.encrypt(kelime, iv: iv);
  final ciphertext = encrypted.base64;
  print(ciphertext);

  // 解密
  final decrypted = encrypter.decryptBytes(enc.Encrypted.fromBase64(ciphertext), iv: iv);
  final decryptedData = utf8.decode(decrypted);
  print(decryptedData); // 输出原字符串
}

错误原因说明

  • fromUtf8()方法的作用是将字符串按UTF-8编码转换成字节数组,而你手里的List已经是原始的密钥/IV字节,转成字符串再转回字节会因为编码兼容性问题(比如部分字节不是合法的UTF-8字符)导致字节内容改变;转成十六进制时每个字符对应两位十六进制,直接让长度翻倍,不符合解密器对32字节密钥、16字节IV的要求。
  • 使用fromList()方法可以直接复用你已有的字节列表,完全保留原始字节数据,满足加密解密的格式要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 02:35:22