Flutter报错:Key length not 128/192/256 bits 如何解决?
解决Flutter AES加密密钥长度报错问题
问题原因
报错Unhandled Exception: Invalid argument(s): Key length not 128/192/256 bits是因为AES加密要求密钥必须是128位(16字节)、192位(24字节)或256位(32字节)。你当前的代码直接基于phoneId字符串的字符长度截取或使用原字符串,当phoneId转成字节后的长度不符合上述三个值时,就会触发该错误(比如phoneId字符长度是20,若每个字符占1字节,字节长度为20,既不是16/24/32)。
解决方案
推荐两种可靠的处理方式:
方式1:通过哈希生成固定长度密钥
使用SHA-256哈希函数对phoneId进行处理,生成固定32字节(256位)的密钥,无论phoneId长度如何,都能满足AES-256的要求。
修改后的代码:
import 'dart:convert'; import 'package:crypto/crypto.dart'; import 'package:encrypt/encrypt.dart'; final String timestamp = DateTime.now().millisecondsSinceEpoch.toString(); // 对phoneId进行SHA-256哈希,生成32字节的密钥 final bytes = utf8.encode(phoneId); final digest = sha256.convert(bytes); final encrypt.Key key = encrypt.Key.fromBytes(digest.bytes); final encrypt.IV iv = encrypt.IV.fromLength(16); final encrypt.Encrypter encrypter = encrypt.Encrypter(encrypt.AES(key)); final String encrypted = encrypter.encrypt(timestamp + phoneId, iv: iv).base16;
注意:需要在pubspec.yaml中添加对应依赖:
dependencies: crypto: ^3.0.3 encrypt: ^5.0.1
方式2:补全/截取字节到指定长度
如果不想用哈希,可将phoneId转成字节后,截取前32字节(不足则补0),确保密钥为256位:
import 'package:encrypt/encrypt.dart'; final String timestamp = DateTime.now().millisecondsSinceEpoch.toString(); final keyBytes = utf8.encode(phoneId); final fixedKeyBytes = List<int>.filled(32, 0); // 复制原字节到固定长度数组,超出则截断,不足则保留原内容其余补0 fixedKeyBytes.setRange(0, keyBytes.length > 32 ? 32 : keyBytes.length, keyBytes); final encrypt.Key key = encrypt.Key(fixedKeyBytes); final encrypt.IV iv = encrypt.IV.fromLength(16); final encrypt.Encrypter encrypter = encrypt.Encrypter(encrypt.AES(key)); final String encrypted = encrypter.encrypt(timestamp + phoneId, iv: iv).base16;
注意事项
- 不要直接基于字符串字符长度处理,因为UTF-8编码中部分字符(如中文)会占多个字节,字符长度不等于字节长度。
- 若使用AES-128或AES-192,只需将固定长度改为16或24字节即可。
内容的提问来源于stack exchange,提问作者Vahit Behrouz
相关产品推荐
相关产品推荐

