190 lines
5.9 KiB
Dart
Executable File
190 lines
5.9 KiB
Dart
Executable File
import 'dart:io';
|
||
|
||
import 'package:hive_flutter/hive_flutter.dart';
|
||
import 'package:crypto/crypto.dart';
|
||
import 'dart:convert';
|
||
import 'package:kaer_with_panels/app/utils/kr_log_util.dart';
|
||
import 'package:path_provider/path_provider.dart';
|
||
|
||
class KRSecureStorage {
|
||
// 创建一个单例实例
|
||
static final KRSecureStorage _instance = KRSecureStorage._internal();
|
||
factory KRSecureStorage() => _instance;
|
||
|
||
// 私有构造函数
|
||
KRSecureStorage._internal();
|
||
|
||
// 存储箱名称
|
||
static const String _boxName = 'kaer_secure_storage';
|
||
|
||
// 加密密钥
|
||
static const String _encryptionKey = 'kaer_secure_storage_key';
|
||
|
||
// 初始化 Hive
|
||
Future<void> kr_initHive() async {
|
||
try {
|
||
// 根据不同平台指定数据库路径
|
||
if (Platform.isMacOS || Platform.isWindows || Platform.isLinux) {
|
||
final baseDir = await getApplicationSupportDirectory();
|
||
KRLogUtil.kr_i('初始化 Hive,路径: ${baseDir.path}', tag: 'SecureStorage');
|
||
|
||
// 确保目录存在
|
||
if (!baseDir.existsSync()) {
|
||
await baseDir.create(recursive: true);
|
||
KRLogUtil.kr_i('已创建 Hive 目录: ${baseDir.path}', tag: 'SecureStorage');
|
||
}
|
||
|
||
await Hive.initFlutter(baseDir.path);
|
||
} else {
|
||
// Android 和 iOS 使用默认路径
|
||
await Hive.initFlutter();
|
||
}
|
||
|
||
// 使用加密适配器
|
||
final key = HiveAesCipher(_generateKey());
|
||
await Hive.openBox(_boxName, encryptionCipher: key);
|
||
KRLogUtil.kr_i('Hive 初始化成功', tag: 'SecureStorage');
|
||
} catch (e, stackTrace) {
|
||
KRLogUtil.kr_e('初始化 Hive 失败: $e', tag: 'SecureStorage');
|
||
KRLogUtil.kr_e('错误类型: ${e.runtimeType}', tag: 'SecureStorage');
|
||
KRLogUtil.kr_e('错误堆栈: $stackTrace', tag: 'SecureStorage');
|
||
|
||
// 对于 Windows 和 Linux,如果初始化失败,尝试删除旧文件并重试
|
||
if (Platform.isWindows || Platform.isLinux) {
|
||
try {
|
||
KRLogUtil.kr_i('尝试清理并重新初始化 Hive', tag: 'SecureStorage');
|
||
final baseDir = await getApplicationSupportDirectory();
|
||
final hiveDir = Directory(baseDir.path);
|
||
|
||
// 查找并删除相关的 Hive 文件
|
||
if (hiveDir.existsSync()) {
|
||
final files = hiveDir.listSync();
|
||
for (var entity in files) {
|
||
if (entity is File) {
|
||
final fileName = entity.path.split(Platform.pathSeparator).last;
|
||
// 删除 Hive 数据库文件(通常是 .hive 或 .lock 文件)
|
||
if (fileName.startsWith(_boxName) ||
|
||
fileName.endsWith('.hive') ||
|
||
fileName.endsWith('.lock')) {
|
||
try {
|
||
await entity.delete();
|
||
KRLogUtil.kr_i('已删除文件: $fileName', tag: 'SecureStorage');
|
||
} catch (deleteError) {
|
||
KRLogUtil.kr_e('删除文件失败: $deleteError', tag: 'SecureStorage');
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 重新初始化
|
||
await Hive.initFlutter(baseDir.path);
|
||
final key = HiveAesCipher(_generateKey());
|
||
await Hive.openBox(_boxName, encryptionCipher: key);
|
||
KRLogUtil.kr_i('Hive 重新初始化成功', tag: 'SecureStorage');
|
||
} catch (retryError, retryStack) {
|
||
KRLogUtil.kr_e('重新初始化 Hive 仍然失败: $retryError', tag: 'SecureStorage');
|
||
KRLogUtil.kr_e('重试堆栈: $retryStack', tag: 'SecureStorage');
|
||
rethrow;
|
||
}
|
||
} else {
|
||
rethrow;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 生成加密密钥
|
||
List<int> _generateKey() {
|
||
final key = utf8.encode(_encryptionKey);
|
||
final hash = sha256.convert(key);
|
||
return hash.bytes;
|
||
}
|
||
|
||
// 获取存储箱
|
||
Box<dynamic> get _box => Hive.box(_boxName);
|
||
|
||
// 存储数据
|
||
Future<void> kr_saveData({required String key, required String value}) async {
|
||
try {
|
||
await _box.put(key, value);
|
||
} catch (e) {
|
||
KRLogUtil.kr_e('存储数据失败: $e', tag: 'SecureStorage');
|
||
}
|
||
}
|
||
|
||
// 读取数据
|
||
Future<String?> kr_readData({required String key}) async {
|
||
try {
|
||
return _box.get(key) as String?;
|
||
} catch (e) {
|
||
KRLogUtil.kr_e('读取数据失败: $e', tag: 'SecureStorage');
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// 删除数据
|
||
Future<void> kr_deleteData({required String key}) async {
|
||
try {
|
||
await _box.delete(key);
|
||
} catch (e) {
|
||
KRLogUtil.kr_e('删除数据失败: $e', tag: 'SecureStorage');
|
||
}
|
||
}
|
||
|
||
// 清除所有数据
|
||
Future<void> kr_clearAllData() async {
|
||
try {
|
||
await _box.clear();
|
||
} catch (e) {
|
||
KRLogUtil.kr_e('清除数据失败: $e', tag: 'SecureStorage');
|
||
}
|
||
}
|
||
|
||
// 检查键是否存在
|
||
Future<bool> kr_hasKey({required String key}) async {
|
||
try {
|
||
return _box.containsKey(key);
|
||
} catch (e) {
|
||
KRLogUtil.kr_e('检查键失败: $e', tag: 'SecureStorage');
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// 保存布尔值
|
||
Future<void> kr_saveBool({required String key, required bool value}) async {
|
||
try {
|
||
await _box.put(key, value);
|
||
} catch (e) {
|
||
KRLogUtil.kr_e('存储布尔值失败: $e', tag: 'SecureStorage');
|
||
}
|
||
}
|
||
|
||
// 获取布尔值
|
||
Future<bool?> kr_getBool({required String key}) async {
|
||
try {
|
||
return _box.get(key) as bool?;
|
||
} catch (e) {
|
||
KRLogUtil.kr_e('读取布尔值失败: $e', tag: 'SecureStorage');
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// 保存整数
|
||
Future<void> kr_saveInt({required String key, required int value}) async {
|
||
try {
|
||
await _box.put(key, value);
|
||
} catch (e) {
|
||
KRLogUtil.kr_e('存储整数失败: $e', tag: 'SecureStorage');
|
||
}
|
||
}
|
||
|
||
// 获取整数
|
||
Future<int?> kr_getInt({required String key}) async {
|
||
try {
|
||
return _box.get(key) as int?;
|
||
} catch (e) {
|
||
KRLogUtil.kr_e('读取整数失败: $e', tag: 'SecureStorage');
|
||
return null;
|
||
}
|
||
}
|
||
} |