You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# .NET5程序加密解密user.config后配置项丢失问题求助

问题原因
  • 根本原因是.NET 5+的System.Configuration.ConfigurationManager包对ClientSettingsSection(也就是项目默认生成的用户设置对应的配置节点类型)的加密解密后序列化逻辑存在缺陷:你当前代码直接将节点作为基类ConfigurationSection处理,调用UnprotectSection()解密后,基类的默认序列化逻辑无法正确识别ClientSettingsSection内部的多配置项集合结构,仅会序列化集合中的最后一个元素到配置文件,同时丢失name属性,就出现了你遇到的只保留最后一个配置项的问题。
解决方案

提供两种可落地的方案,你可以根据需求选择:

方案1:单独加密敏感字段(更推荐,稳定性更高)

不需要加密整个配置节点,只对密码这类敏感字段单独做对称加密后存储,使用时再解密即可,完全规避整个节点加密的兼容性问题:

  • 选择AES等对称加密算法,生成固定的密钥存储在程序中
  • 保存密码时先加密再写入配置的Password字段
  • 读取密码时取出加密字符串解密后使用
    这种方案不需要改动配置结构,兼容性更好,也不会出现配置丢失的问题。

方案2:修复原有加密整个节点的逻辑

如果确实需要加密整个用户配置节点,修改你的加解密代码,操作节点时使用强类型的ClientSettingsSection,并在保存前强制标记所有配置元素为已修改:

加密方法修改示例

private void ProtectSettings()
{ 
    System.Configuration.Configuration config =
            ConfigurationManager.OpenExeConfiguration(
            ConfigurationUserLevel.PerUserRoamingAndLocal);

    string provider = "DataProtectionConfigurationProvider";
    string sectionName = "userSettings/" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Name + ".Properties.Settings";
    // 转成强类型的ClientSettingsSection
    ClientSettingsSection settingsSection = config.GetSection(sectionName) as ClientSettingsSection;
    if (settingsSection != null)
    {
        if (!settingsSection.SectionInformation.IsProtected && !settingsSection.ElementInformation.IsLocked)
        {
            settingsSection.SectionInformation.ProtectSection(provider);
            settingsSection.SectionInformation.ForceSave = true;
            // 保存前先刷新设置避免缓存问题
            Properties.Settings.Default.Reload();
            config.Save(ConfigurationSaveMode.Full);
            Properties.Settings.Default.Reload();
        }
    }
}

解密方法修改示例

private static void UnProtectSettings()
{
    System.Configuration.Configuration config =
            ConfigurationManager.OpenExeConfiguration(
            ConfigurationUserLevel.PerUserRoamingAndLocal);

    string sectionName = "userSettings/" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Name + ".Properties.Settings";
    ClientSettingsSection settingsSection = config.GetSection(sectionName) as ClientSettingsSection;
    if (settingsSection != null)
    {
        if (settingsSection.SectionInformation.IsProtected && !settingsSection.ElementInformation.IsLocked)
        {
            settingsSection.SectionInformation.UnprotectSection();
            // 手动标记所有配置元素为已修改,确保全部被序列化
            foreach (SettingsElement setting in settingsSection.Settings)
            {
                setting.ElementInformation.IsModified = true;
            }
            settingsSection.SectionInformation.ForceSave = true;
            config.Save(ConfigurationSaveMode.Full);
            Properties.Settings.Default.Reload();
        }
    }
}

内容的提问来源于stack exchange,提问作者Korny86

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 01:24:04