123 lines
3.5 KiB
Dart
Executable File
123 lines
3.5 KiB
Dart
Executable File
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>;
|
||
}
|
||
}
|