.net - 如何加密 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": "*"
}
解决方案
根据您的描述,如果您想加密 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; }
}
结果:
推荐阅读
- mysql - 如何避免在mysql视图的子视图中进行全表扫描
- django - 如何在 django 中为用户登录实现自定义身份验证
- react-native - this.nameOfFunction 调用时不是函数
- python - 如何在将列表与另一个变量进行比较时引用列表中的多个项目?
- cube - 是否可以在 TM1s.cfg 的 DataBaseDirectory 参数中使用相对路径?
- progressive-web-apps - 第二次刷新后正在存储缓存
- kubernetes - Kubernetes PVC 删除 POD 的内容
- apache-flink - 失去检查点协调员后是否有可能恢复
- java - 不同类方法的组成
- reactjs - 在 goDaddy 主机上上传由 create-react-app 创建的 react 应用程序的步骤