Explorar o código

把 secret.json 的内容从明文改为加密存储

HerobrineXia hai 1 mes
pai
achega
c20feff8ab
Modificáronse 2 ficheiros con 14 adicións e 4 borrados
  1. 1 1
      .agents/Shared/架构分析.md
  2. 13 3
      Shared/General/Config.cs

+ 1 - 1
.agents/Shared/架构分析.md

@@ -26,7 +26,7 @@
 
 - 首次访问默认配置前调用 `Main.Init(appName)`;它设置应用名和默认正则超时,不初始化 WPF 或文件日志。默认 provider 静态初始化后,修改应用名不会迁移其路径。
 - `ConfigEntry<T>` 绑定固定 provider,`DynamicConfigEntry<T>` 每次操作传 provider。替换 `ConfigProviders.Default` 不改变已有 entry 的绑定。
-- `ConfigProviders.Secret` 位于 `Paths.AppData/secret.json`,没有应用名子目录,也不自动加密。当前非 null 加密写入会先修改缓存再抛 `NotImplementedException`。
+- `ConfigUtils.GetSecret` 独立读取 `Paths.AppData/Meloong/Dev/secret.json`,使用 `CryptographyUtils.AesDecrypt` ,首次读取后缓存 JSON 对象;不使用配置 provider、不参与 SaveAll。文件不存在或键为 null/缺失时抛出缺键异常;解密或解析失败抛出脱敏异常,不覆盖文件。默认密钥仅用于避免明文存储,不提供可靠保密保护。
 - 同一 provider 的同一键固定使用同一类型;显式 JSON null 算已存值。Get 返回对象缓存,修改对象后需 Edit/Set 才安排保存;Edit 不是原子更新。
 - Set 即使值相同也触发 Changed;动态 entry 的 Changed 不携带 provider。PreviewGet 仅修正本次读取,不自动写回。
 - JSON 写入防抖 500 ms;明确落盘点可用 `ConfigUtils.SaveAll()`。DiscardCache 不保存变更;Save 写盘失败不保证恢复 dirty。整文件加载失败回退空对象,不代表所有键读取错误都会回退默认值。

+ 13 - 3
Shared/General/Config.cs

@@ -118,7 +118,6 @@ public class JsonConfigProvider : IConfigProvider {
 
 public static class ConfigProviders {
     public static JsonConfigProvider Default = new(Path.Combine(Paths.AppDataThenName, "config.json"));
-    public static readonly JsonConfigProvider Secret = new(Path.Combine(Paths.AppData, "secret.json"));
 }
 
 #endregion
@@ -224,8 +223,19 @@ public static class ConfigUtils {
         }
     }
 
-    /// <summary>从 secret.json 中读取特定密钥,如果未找到对应密钥则抛出异常。</summary>
+    private static readonly Lazy<JObject> secret = new(() => {
+        string filePath = Path.Combine(Paths.AppData, "Meloong", "Dev", "secret.json");
+        try {
+            return FileUtils.Exists(filePath)
+                ? JObject.Parse(CryptographyUtils.AesDecrypt(FileUtils.ReadAsString(filePath))!) : [];
+        } catch {
+            // 解密及 JSON 异常可能包含凭据内容,不保留原始异常,也不回退空配置。
+            throw new InvalidDataException($"读取密钥文件失败({filePath}),请检查文件内容与加密格式。");
+        }
+    });
+
+    /// <summary>从加密的 secret.json 中读取特定密钥,首次读取后缓存;如果未找到对应密钥则抛出异常。</summary>
     public static string GetSecret(string key)
-        => ConfigProviders.Secret.Read<string>(key, null, false) ?? throw new KeyNotFoundException($"未找到密钥:{key}");
+        => secret.Value.Value<string>(key) ?? throw new KeyNotFoundException($"未找到密钥:{key}");
 
 }