如何使用Dart解密AES-EAX模式加密的字符串?
Dart中实现AES-EAX模式解密的方法
Dart官方的crypto库确实没有直接支持AES-EAX模式,你需要使用第三方密码学库pointycastle来实现,这是Dart生态里最常用的密码学工具库之一。
实现步骤
- 添加依赖
在项目的pubspec.yaml中添加pointycastle依赖:
dependencies: pointycastle: ^3.7.3
执行dart pub get安装依赖。
- 解密代码实现
假设你的加密字符串是Base64编码,nonce也是Base64编码,密钥为16字节(AES-128),标签长度为16字节(EAX默认推荐长度),示例代码如下:
import 'dart:convert'; import 'package:pointycastle/api.dart'; import 'package:pointycastle/block/aes.dart'; import 'package:pointycastle/stream/eax.dart'; Uint8List decryptAesEax( String encryptedBase64, String nonceBase64, Uint8List key, { int tagLength = 16, // EAX标签长度,通常为16字节 }) { // 解码加密字符串和nonce final encryptedData = base64Decode(encryptedBase64); final nonce = base64Decode(nonceBase64); // 拆分密文和标签:EAX加密结果通常是密文 + 标签 final ciphertext = encryptedData.sublist(0, encryptedData.length - tagLength); final tag = encryptedData.sublist(encryptedData.length - tagLength); // 初始化EAX模式的AES密码器 final cipher = EaxBlockCipher(AesEngine()); final params = ParametersWithIV(KeyParameter(key), nonce); cipher.init(false, params); // false表示解密模式 // 关联数据(如果加密时有使用,这里要传入相同的关联数据;没有则传空) final associatedData = Uint8List(0); if (associatedData.isNotEmpty) { cipher.processAadBytes(associatedData); } // 设置标签 cipher.tag = tag; // 执行解密 final output = Uint8List(ciphertext.length); var offset = 0; offset += cipher.processBytes(ciphertext, 0, ciphertext.length, output, offset); offset += cipher.doFinal(output, offset); return output; } // 使用示例 void main() { const encryptedStr = "你的加密Base64字符串"; const nonceStr = "你的nonce的Base64字符串"; final key = Uint8List.fromList(utf8.encode("16字节的密钥")); // AES-128密钥 final decryptedBytes = decryptAesEax(encryptedStr, nonceStr, key); final decryptedText = utf8.decode(decryptedBytes); print(decryptedText); }
关键注意事项
- 密钥长度:AES支持128/192/256位密钥,对应16/24/32字节,要和加密时使用的密钥长度一致。
- Nonce:EAX模式的nonce不需要保密,但必须唯一,不能重复使用同一个nonce和密钥加密不同数据,否则会破坏安全性。
- 关联数据(AAD):如果加密时使用了关联数据,解密时必须传入完全相同的关联数据,否则解密会失败。
- 标签拆分:确保你拆分密文和标签的方式和加密时一致,有些实现会把标签放在前面,但大多数是放在密文之后。
内容的提问来源于stack exchange,提问作者exactly
相关产品推荐
相关产品推荐

