hi-client/lib/app/utils/kr_aes_util.dart
2025-10-17 15:28:40 +08:00

123 lines
3.5 KiB
Dart
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:convert';
import 'dart:typed_data';
import 'package:crypto/crypto.dart';
import 'package:encrypt/encrypt.dart' as encrypt;
/// AES加密解密工具类
/// 算法AES-256-CBC
/// 填充PKCS7
/// 密钥生成SHA-256(keyStr) → 32字节
/// IV生成SHA-256(MD5(nonce) + keyStr) → 取前16字节
class KRAesUtil {
/// 生成密钥使用SHA-256
static encrypt.Key _generateKey(String keyStr) {
final keyBytes = sha256.convert(utf8.encode(keyStr)).bytes;
return encrypt.Key(Uint8List.fromList(keyBytes));
}
/// 生成IV使用MD5 + SHA-256
static encrypt.IV _generateIv(String ivStr, String keyStr) {
// 首先用MD5处理ivStr
final md5Hash = md5.convert(utf8.encode(ivStr)).bytes;
// 将MD5结果转换为十六进制字符串
final md5Hex = _hexEncode(md5Hash);
// 拼接 md5Hex + keyStr
final combinedKey = md5Hex + keyStr;
// 对拼接后的字符串做SHA-256
final finalHash = sha256.convert(utf8.encode(combinedKey)).bytes;
// 取前16字节作为IV
return encrypt.IV(Uint8List.fromList(finalHash.sublist(0, 16)));
}
/// 将字节数组转换为十六进制字符串
static String _hexEncode(List<int> bytes) {
return bytes.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join('');
}
/// 加密数据
///
/// 参数:
/// - plainText: 要加密的明文
/// - keyStr: 加密密钥
///
/// 返回:
/// - Map包含两个字段: data(加密后的Base64字符串), time(ISO8601时间戳)
static Map<String, String> encryptData(String plainText, String keyStr) {
// 生成时间戳
final nonce = DateTime.now().toIso8601String();
// 生成密钥和IV
final key = _generateKey(keyStr);
final iv = _generateIv(nonce, keyStr);
// 创建加密器 (AES-256-CBC with PKCS7 padding)
final encrypter = encrypt.Encrypter(
encrypt.AES(key, mode: encrypt.AESMode.cbc, padding: 'PKCS7'),
);
// 加密
final encrypted = encrypter.encrypt(plainText, iv: iv);
return {
'data': encrypted.base64,
'time': nonce,
};
}
/// 解密数据
///
/// 参数:
/// - encryptedData: 加密后的Base64字符串
/// - nonce: 时间戳
/// - keyStr: 解密密钥
///
/// 返回:
/// - 解密后的明文字符串
static String decryptData(String encryptedData, String nonce, String keyStr) {
// 生成密钥和IV
final key = _generateKey(keyStr);
final iv = _generateIv(nonce, keyStr);
// 创建解密器 (AES-256-CBC with PKCS7 padding)
final encrypter = encrypt.Encrypter(
encrypt.AES(key, mode: encrypt.AESMode.cbc, padding: 'PKCS7'),
);
// 解密
final decrypted = encrypter.decrypt64(encryptedData, iv: iv);
return decrypted;
}
/// 加密JSON对象
///
/// 参数:
/// - jsonData: 要加密的JSON对象
/// - keyStr: 加密密钥
///
/// 返回:
/// - Map包含两个字段: data(加密后的Base64字符串), time(ISO8601时间戳)
static Map<String, String> encryptJson(Map<String, dynamic> jsonData, String keyStr) {
final plainText = jsonEncode(jsonData);
return encryptData(plainText, keyStr);
}
/// 解密JSON对象
///
/// 参数:
/// - encryptedData: 加密后的Base64字符串
/// - nonce: 时间戳
/// - keyStr: 解密密钥
///
/// 返回:
/// - 解密后的JSON对象
static Map<String, dynamic> decryptJson(String encryptedData, String nonce, String keyStr) {
final decrypted = decryptData(encryptedData, nonce, keyStr);
return jsonDecode(decrypted) as Map<String, dynamic>;
}
}