首页 > 解决方案 > 如何加密 appsettings.js 字符串并且仍然可用?

问题描述

我已经使用 appsettings.js(附在下面)在邮递员中进行了登录,并且由于 appsettings.js 中的字符串非常敏感并且也能够轻松访问,我是否可以让它们安全或我如何加密它们?? 抱歉,如果我有任何错误,因为我对此很陌生。谢谢,请谅解。谢谢

{
    "ConnectionStrings": {
        "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=HealthAPI;Trusted_Connection=True;MultipleActiveResultSets=true"
    },
    "Jwt": {
        "Site": "http://www.security.org",
        "SigningKey": "Paris Berlin Cairo Sydney Tokyo Beijing Rome London Athens",
        "ExpiryInMinutes": "60"
    },
    "Logging": {
        "LogLevel": {
            "Default": "Warning"
        }
    },
    "AllowedHosts": "*"
}

标签: .netjsonasp.net-core

解决方案


根据您的描述,如果您想加密 appsettings.json 部分的值,我建议您可以尝试使用 asp.net core 的 DataProtection Dpapi 来加密和解密该值。

注意:对于appsettings.json的加解密,我们有很多解决方案,我建议你也可以参考这个SO question

你可以像下面这样创建一个扩展类;</p>

   public static class IServiceCollectionExtensions
    {
        public static IServiceCollection AddProtectedConfiguration(this IServiceCollection services)
        {
            services
                .AddDataProtection()
                .PersistKeysToFileSystem(new DirectoryInfo(@"c:\keys"))
                .ProtectKeysWithDpapi();

            return services;
        }

        public static IServiceCollection ConfigureProtected<TOptions>(this IServiceCollection services, IConfigurationSection section) where TOptions : class, new()
        {
            return services.AddSingleton(provider =>
            {
                var dataProtectionProvider = provider.GetRequiredService<IDataProtectionProvider>();
                var protectedSection = new ProtectedConfigurationSection(dataProtectionProvider, section);

                var options = protectedSection.Get<TOptions>();
                return Options.Create(options);
            });
        }

        private class ProtectedConfigurationSection : IConfigurationSection
        {
            private readonly IDataProtectionProvider _dataProtectionProvider;
            private readonly IConfigurationSection _section;
            private readonly Lazy<IDataProtector> _protector;

            public ProtectedConfigurationSection(
                IDataProtectionProvider dataProtectionProvider,
                IConfigurationSection section)
            {
                _dataProtectionProvider = dataProtectionProvider;
                _section = section;

                _protector = new Lazy<IDataProtector>(() => dataProtectionProvider.CreateProtector(section.Path));
            }

            public IConfigurationSection GetSection(string key)
            {
                return new ProtectedConfigurationSection(_dataProtectionProvider, _section.GetSection(key));
            }

            public IEnumerable<IConfigurationSection> GetChildren()
            {
                return _section.GetChildren()
                    .Select(x => new ProtectedConfigurationSection(_dataProtectionProvider, x));
            }

            public IChangeToken GetReloadToken()
            {
                return _section.GetReloadToken();
            }

            public string this[string key]
            {
                get => GetProtectedValue(_section[key]);
                set => _section[key] = _protector.Value.Protect(value);
            }

            public string Key => _section.Key;
            public string Path => _section.Path;

            public string Value
            {
                get => GetProtectedValue(_section.Value);
                set => _section.Value = _protector.Value.Protect(value);
            }

            private string GetProtectedValue(string value)
            {
                if (value == null)
                    return null;

                return _protector.Value.Unprotect(value);
            }
        }
    }

然后您可以将这些代码添加到您的 startup.cs ConfigureServices 方法中以启用数据生产:

        services.AddProtectedConfiguration();

要加密 appsettings.json,您可以尝试创建如下控制器:

[ApiController]
[Route("[controller]")]
 public class WeatherForecastController : ControllerBase
{
    private readonly IDataProtectionProvider _dataProtectionProvider;
    private readonly JWT _options;

    public WeatherForecastController(IDataProtectionProvider dataProtectionProvider, IOptions<JWT>  options)
    {
        _logger = logger;
        _IConfiguration = configuration;
        _dataProtectionProvider = dataProtectionProvider;
        _options = options.Value;
    }

    [Route("encrypt"), HttpGet, HttpPost]
    public string Encrypt(string section, string value)
    {
        var protector = _dataProtectionProvider.CreateProtector(section);
        return protector.Protect(value);
    }

}

然后你可以调用https://localhost/weatherforecast/encrypt?section=Jwt:ExpiryInMinutes&value=60,https://localhost/weatherforecast/encrypt?section=Jwt:SigningKey&value=Paris Berlin Cairo Sydney Tokyo Beijing Rome London Athens获取三个加密值,并将加密值替换为 asp.net 核心 json 文件中的默认值,如下所示:</p>

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Jwt": {
    "Site": "CfDJ8FPvxsDZrudHuLb0eHtPtst2lTrqwLJ3-6nCSj0e2wy6G2vtFZkGWPjlJGBKWJdCvJ0KIoq7konHIERH11_n4slwbzuzQNrZ4FC_oy9wMwj9hMIA4ueNNECHRl19yuiluvZ80XFjs2Uv0vm51pCJ7i0",
    "SigningKey": "CfDJ8FPvxsDZrudHuLb0eHtPtssQuzQVurrRyngNpmf1hJV_tUKW2F-7HnasihRtP19ZrGr8E7F6rMqCljaUcHN63VxZbB6JDqm4kvdLIEP3pNmzVexxpiajQYXf--ZnONu-ZYXWT_gcQcju5V9wY8UJSY8jE0f8y2G4kuzL27rL6P4v7U4w9DeXtu_mgUMej4f04w",
    "ExpiryInMinutes": "CfDJ8FPvxsDZrudHuLb0eHtPtsvMeMtrytasZ95VYSca8LgKbFXL4WIvBZ_dWGryT2g6ykW0kioQz9_i6IyS8DbX_81IgWXs4le-fix3yTc4D7BAJDM82D1Sp4P8FNNq4tBoHA"
  }
}

然后您可以添加 services.ConfigureProtected方法来注册配置选项值并使用 DI 直接在服务中获取它。

具体可以参考以下代码:

startup.cs 的 ConfigureServices 方法:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddProtectedConfiguration();
        services.ConfigureProtected<JWT>(Configuration.GetSection("Jwt"));
        services.AddControllers();
      }

用法:

[ApiController]
[Route("[controller]")]
 public class WeatherForecastController : ControllerBase
{
    private readonly IDataProtectionProvider _dataProtectionProvider;
    private readonly JWT _options;

    public WeatherForecastController(IDataProtectionProvider dataProtectionProvider, IOptions<JWT>  options)
    {
        _logger = logger;
        _IConfiguration = configuration;
        _dataProtectionProvider = dataProtectionProvider;
        _options = options.Value;
    }

    [Route("encrypt"), HttpGet, HttpPost]
    public string Encrypt(string section, string value)
    {
        var protector = _dataProtectionProvider.CreateProtector(section);
        return protector.Protect(value);
    }

       [HttpGet]
    public string Get()
    {
       var result = _options.SigningKey;

       return result;

     }

}

智威汤逊类:

public class JWT
{
    public string Site { get; set; }
    public string SigningKey { get; set; }
    public string ExpiryInMinutes { get; set; }
}

结果:

在此处输入图像描述


推荐阅读