Flutter encrypt库AES加密结果无法在Kotlin/Java中正确解密求助
问题排查与解决方案
核心问题定位
AES是国际通用标准算法,不同语言的标准实现不存在底层差异,问题均来自代码疏漏,按优先级排查以下点:
1. Flutter端Key转换逻辑错误(最高概率)
你当前AESEncryptor的encrypt方法中,针对Key类型输入的转换逻辑完全冗余且极易出错:
// 错误写法,冗余且易出问题 if (data.runtimeType == Key) { data = toInt(combineByTwo(data.base16.split(''))); }
Key类本身已提供原生字节数组属性bytes,直接使用即可,绕base16转换只要combineByTwo或toInt逻辑有一点问题(比如字节顺序颠倒、十六进制大小写处理错误),都会导致加密明文完全错误。
修改为:
if (data.runtimeType == Key) { data = data.bytes; }
2. Kotlin端IV构造错误(次高概率)
Flutter端的IV是通过fromBase16将32位0的十六进制字符串转为16个0x00的字节数组,如果Kotlin端构造IV时错误地将字符串直接转字节:
// 错误写法,得到的是16个0x30(字符'0'的ASCII码) val iv = IvParameterSpec("0000000000000000".toByteArray())
会直接导致IV不匹配,解密结果完全错误。正确构造方式:
// 正确写法,生成16个0x00的字节数组 val iv = IvParameterSpec(ByteArray(16) { 0x00 })
3. 其他参数一致性校验
- 确认Kotlin端的密钥字节数组和Flutter端
mainKey完全对应,每个字节的值不要写错(比如不要把0x04写成0x40) - 确认两端传输加密数据时,字节转十六进制/字符串的逻辑一致,没有出现字节顺序颠倒、编码错误的问题
- 测试时暂时去掉Kotlin端的
padFrame/unpadFrame逻辑,直接解密16字节的测试密文,排除填充逻辑的影响
验证测试用例
你可以直接运行以下Kotlin测试代码验证核心逻辑是否正确:
import javax.crypto.Cipher import javax.crypto.spec.IvParameterSpec import javax.crypto.spec.SecretKeySpec fun main() { // 对应Flutter的mainKey val key = byteArrayOf( 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04 ) // 全0 IV val iv = IvParameterSpec(ByteArray(16)) // 对应Flutter输出的加密结果 val encrypted = byteArrayOf( 0x2C, 0xC3.toByte(), 0x81.toByte(), 0xE9.toByte(), 0x68, 0xD2.toByte(), 0x83.toByte(), 0x30, 0xF7.toByte(), 0xA9.toByte(), 0x5C, 0x4F, 0x67, 0x06, 0x3F, 0x5B.toByte() ) // 解密 val cipher = Cipher.getInstance("AES/CBC/NoPadding") cipher.init(Cipher.DECRYPT_MODE, SecretKeySpec(key, "AES"), iv) val decrypted = cipher.doFinal(encrypted) // 打印十六进制结果,正常应输出 ad 11 b4 6b 61 69 5f e9 12 e7 05 35 b8 95 3a 09 println(decrypted.joinToString(" ") { "%02X".format(it) }) }
如果测试输出正确,说明核心加解密逻辑没有问题,只需排查上层传参、数据转换的错误即可。
内容的提问来源于stack exchange,提问作者lou habert
相关产品推荐
相关产品推荐

