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

将Java AES/CBC/PKCS5Padding加解密代码转Dart遇错求助

解决AES/CBC/PKCS5Padding解密的块大小异常问题

你遇到的Input data length must be a multiple of cipher's block size异常,核心原因是没有正确拆分IV(初始化向量)和密文数据。在Java的AES/CBC实现中,通常会把16字节的IV附加在密文头部一起Base64编码,解密时需要先拆分出IV,再用剩余的密文数据进行解密。

完整Dart解密实现

首先确保在pubspec.yaml中添加依赖:

dependencies:
  pointycastle: ^3.7.3

然后使用以下代码解密:

import 'dart:convert';
import 'package:pointycastle/api.dart';
import 'package:pointycastle/block/aes.dart';
import 'package:pointycastle/block/modes/cbc.dart';
import 'package:pointycastle/paddings/pkcs7.dart';

String decryptAesCbc(String encryptedBase64, String key) {
  // 1. Base64解码密文
  final encryptedBytes = base64Decode(encryptedBase64);
  
  // 2. 拆分IV(前16字节)和实际密文(剩余部分)
  final iv = encryptedBytes.sublist(0, 16);
  final cipherText = encryptedBytes.sublist(16); // 关键:这里不要错误指定结束索引,直接取从16到末尾的所有字节

  // 3. 初始化AES/CBC模式
  final cipher = CBCBlockCipher(AESFastEngine());
  final params = ParametersWithIV<KeyParameter>(
    KeyParameter(utf8.encode(key)),
    iv,
  );
  cipher.init(false, params); // false代表解密模式

  // 4. 处理PKCS5填充(和PKCS7填充在16字节块大小下等价)
  final padding = PKCS7Padding();
  padding.init(null);

  // 5. 执行解密
  final output = Uint8List(cipherText.length);
  var offset = cipher.processBlock(cipherText, 0, output, 0);
  if (cipherText.length > offset) {
    offset += cipher.processBlock(cipherText, offset, output, offset);
  }

  // 6. 去除填充并转明文
  final decryptedBytes = padding.unpad(output);
  return utf8.decode(decryptedBytes);
}

// 测试示例
void main() {
  const encrypted = '8tyHRaQCsxmmGW2xPBFYx/PALmvHkmjx/TzaXC2rIv0=';
  const key = '你的AES密钥'; // 替换为Java代码中使用的密钥,长度需为16/24/32字节
  try {
    final plainText = decryptAesCbc(encrypted, key);
    print('解密结果:$plainText'); // 预期输出:C123492349C1CT20230206130645
  } catch (e) {
    print('解密失败:$e');
  }
}

关键注意事项

  • IV拆分逻辑:如果你的Java加密代码是将IV拼接在密文头部,那么encryptedBytes.sublist(16)就是正确的密文提取方式,之前的错误大概率是这里的sublist参数写错(比如错误指定了结束索引,导致提取的密文长度不是16的倍数)。
  • 填充兼容性:PKCS5Padding和PKCS7Padding在块大小为16字节时完全等价,所以Dart中用PKCS7Padding即可兼容Java的PKCS5Padding。
  • 密钥一致性:必须保证Dart中使用的密钥和Java代码中的密钥完全一致,密钥长度需符合AES标准(128位/192位/256位,对应16/24/32字节)。

内容的提问来源于stack exchange,提问作者Malavika k s

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 20:50:28