Reputation: 29
I've done a login in postman with appsettings.js(attached below) and as the strings in appsettings.js is very sensitive and also being able to access easily, is there away i can make them secured or how i can i encrypt them?? sorry if i have any mistakes cause I'm very new to this.. thank you and please be understanding. Thank you
{
"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": "*"
}
Upvotes: 1
Views: 645
Reputation: 27962
According to your description, if you want to encrypt the appsettings.json section value, I suggest you could try to use asp.net core's DataProtection Dpapi to encrypt and decrypt the value.
Notice: For encrypt and decrypt the appsettings.json, we have a lot of solutions, I suggest you could also refer to this SO question.
You could create a extension class like below;
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);
}
}
}
Then you could add these codes into your startup.cs ConfigureServices method to enable the data production:
services.AddProtectedConfiguration();
To encrypt the appsettings.json you could try to create a controller like below:
[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);
}
}
Then you could call 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
to get three encrpted value and replace the encrtpted value with the default value in asp.net core json file like below:
{
"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"
}
}
Then you could add services.ConfigureProtected
method to register the configuration option value and directly get it in services by using DI.
Details, you could refer to below codes:
The startup.cs ConfigureServices methods:
public void ConfigureServices(IServiceCollection services)
{
services.AddProtectedConfiguration();
services.ConfigureProtected<JWT>(Configuration.GetSection("Jwt"));
services.AddControllers();
}
Usage:
[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;
}
}
JWT Class:
public class JWT
{
public string Site { get; set; }
public string SigningKey { get; set; }
public string ExpiryInMinutes { get; set; }
}
Result:
Upvotes: 1