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

如何在Flutter/Dart中解密Laravel AES加密字符串?

Laravel AES-CBC 加密串的 Flutter/Dart 解密方案

核心流程说明

Laravel 的 Crypt::encryptString 采用 AES-256-CBC 模式,加密结果是经过 Base64 编码的 JSON 结构,包含 iv(初始化向量)、value(密文)、mac(消息校验码)三个字段。解密需严格遵循 Laravel 的加密规范,以下是基于 pointycastle 包的正确实现:

步骤 1:添加依赖

在 pubspec.yaml 中引入包:

dependencies:
  pointycastle: ^3.7.3

步骤 2:完整解密代码

import 'dart:convert';
import 'package:pointycastle/export.dart';

String decryptLaravelAes(String encryptedString, String rawKey) {
  // 1. 解码 Laravel 加密串
  final encryptedBytes = base64Decode(encryptedString);
  final jsonStr = utf8.decode(encryptedBytes);
  final data = jsonDecode(jsonStr) as Map<String, dynamic>;

  final ivBytes = base64Decode(data['iv'] as String);
  final ciphertextBytes = base64Decode(data['value'] as String);
  final mac = data['mac'] as String;

  // 2. 处理密钥:Laravel 要求密钥为 32 字节(AES-256),原始密钥需通过 SHA256 哈希生成
  final keyBytes = sha256.convert(utf8.encode(rawKey)).bytes;

  // 3. 验证 MAC(防止数据篡改,可选但建议保留)
  final hmac = HMac(SHA256Digest(), 64)..init(KeyParameter(keyBytes));
  final macInput = base64Encode(ivBytes) + base64Encode(ciphertextBytes);
  final computedMac = hex.encode(hmac.convert(utf8.encode(macInput)).bytes);
  if (computedMac != mac) throw Exception('MAC 校验失败,数据可能已被篡改');

  // 4. AES-CBC 解密
  final cipher = CBCBlockCipher(AESEngine())
    ..init(false, ParametersWithIV(KeyParameter(keyBytes), ivBytes));
  final decryptedBytes = _processBlocks(cipher, ciphertextBytes);

  // 5. 去除 PKCS7 填充
  final padding = PKCS7Padding();
  padding.init(null);
  final unpaddedBytes = padding.unpad(decryptedBytes);

  return utf8.decode(unpaddedBytes);
}

// 块处理辅助函数
Uint8List _processBlocks(BlockCipher cipher, Uint8List input) {
  final output = Uint8List(input.length);
  for (var i = 0; i < input.length; i += cipher.blockSize) {
    cipher.processBlock(input, i, output, i);
  }
  return output;
}

// 调用示例
void main() {
  final laravelEncryptedStr = "替换为你的Laravel加密串";
  final encryptionKey = "theencryptionkey";
  try {
    final result = decryptLaravelAes(laravelEncryptedStr, encryptionKey);
    print("解密结果:$result");
  } catch (e) {
    print("解密失败:$e");
  }
}

常见问题排查

  • 密钥不匹配:Laravel 使用 32 字节密钥(AES-256),如果你的原始密钥长度不足,需通过 SHA256 哈希生成(代码已处理);若 Laravel 的 APP_KEY 带 base64: 前缀,需先去掉前缀再 Base64 解码得到密钥字节。
  • MAC 校验失败:确保计算 MAC 时的输入是 base64(iv) + base64(密文),且密钥与 Laravel 完全一致。
  • 填充错误:Laravel 默认使用 PKCS7 填充,解密后必须调用 unpad 去除填充,否则会出现乱码或报错。
  • IV 处理错误:IV 是 16 字节的 Base64 字符串,必须解码为二进制数据后传入解密器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 03:53:24