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

如何在Flutter中实现与Java一致的AES解密?解决密钥长度报错

问题:Flutter AES256解密报错「Key length not 128/192/256 bits」

我尝试将Java Spring Boot的AES256解密代码转换为Flutter代码,使用了encrypt库,但运行时出现以下错误:

Key length not 128/192/256 bits.

Java Spring Boot 原解密代码

public static String decryptAES256(String str, String secretKey) throws java.io.UnsupportedEncodingException,
                NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
                InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
            String AES = "AES";
            String AES_PADDING = "AES/CBC/PKCS5Padding";
            byte[] keyData = java.util.Base64.getDecoder().decode(secretKey);
            String iv = secretKey.substring(0, 16);
            SecretKey secureKey = new SecretKeySpec(keyData, AES);
            Cipher c = Cipher.getInstance(AES_PADDING);
            c.init(Cipher.DECRYPT_MODE, secureKey, new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8)));
            byte[] byteStr = Base64.getDecoder().decode(str.getBytes());
            return new String(c.doFinal(byteStr), StandardCharsets.UTF_8);
        }

我写的Flutter错误代码

final encData = codefModel.data!.encData!;
    final key = en.Key.fromUtf8(decryptKey);
    final b64key = en.Key.fromUtf8(base64Url.encode(key.bytes));
    final iv = en.IV.fromLength(16);
    final encrypter = en.Encrypter(en.AES(b64key, mode: en.AESMode.cbc));
    logger.d(encrypter.decrypt64(encData, iv: iv));

问题分析与修正

原Flutter代码的错误点

  1. 密钥处理逻辑完全颠倒:Java是直接Base64解码密钥字符串得到原始密钥字节,而你的代码先把密钥转成UTF-8字节再Base64编码,导致密钥长度不符合AES256要求(256位=32字节)。
  2. IV生成错误:Java是取密钥字符串的前16个字符作为IV,而你的代码生成了随机IV,和原逻辑不匹配。
  3. 填充方式未明确指定:Java用的是PKCS5Padding,需要在Flutter中指定对应的兼容填充方式。

修正后的Flutter解密代码

import 'dart:convert';
import 'package:encrypt/encrypt.dart' as en;

// ... 你的业务代码 ...
final encData = codefModel.data!.encData!;
final decryptKey = "你的密钥字符串"; // 对应Java的secretKey参数

try {
  // 1. 处理密钥:Base64解码密钥字符串,和Java逻辑一致
  final keyBytes = base64Decode(decryptKey);
  final key = en.Key(keyBytes);

  // 2. 处理IV:取密钥字符串的前16个字符转UTF-8字节,和Java逻辑一致
  final ivStr = decryptKey.substring(0, 16);
  final iv = en.IV.fromUtf8(ivStr);

  // 3. 初始化加密器:CBC模式+PKCS7Padding(和Java的PKCS5Padding在128位块下兼容)
  final encrypter = en.Encrypter(
    en.AES(
      key,
      mode: en.AESMode.cbc,
      padding: en.AESPadding.pkcs7,
    ),
  );

  // 4. 解密:自动处理Base64解码,对应Java的Base64解码步骤
  final decryptedText = encrypter.decrypt64(encData, iv: iv);
  logger.d(decryptedText);
} catch (e) {
  logger.e('解密失败:$e');
}

关键说明

  • 密钥正确性:确保decryptKey是和Java端一致的Base64编码字符串,解码后必须是32字节(256位),否则仍会报密钥长度错误。
  • IV一致性:必须严格和Java逻辑保持一致,取密钥字符串的前16位,否则解密结果会乱码或失败。
  • 填充兼容性:AES的块大小是128位,PKCS5Padding和PKCS7Padding在此场景下完全兼容,所以用encrypt库的pkcs7即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 01:35:25