我想使用我的appsettings.json存储“主密码”。
然后,此主密码将用于打开由此优秀密码存储包生成的私钥(及其后续密码存储区):https://github.com/neosmart/SecureStore
问题是,我想不出有什么方法可以加密主密码。我知道在.NET 4.5中,可以执行以下操作:
1)将您的密码放入web.config文件
2)运行此脚本:aspnet_regiis.exe -pef appSettings“C:\ myfolder”
3)您的密码最终会被加密 - 但您的程序会安全阅读。
https://www.codeproject.com/Articles/599416/Encrypting-ASP-NET-Application-Settings
我是以正确的方式做到这一点还是有更好的做法?
答案 0 :(得分:4)
JSON配置提供程序不支持加密。目前,唯一支持加密配置的开箱即用服务提供商是Azure KeyVault。无论您的应用程序是否实际托管在Azure上,您都可以使用KeyVault,虽然它不是免费的,但在大多数情况下,这些许可可能只会花费几美分。
那就是说,Core的一部分美妙之处在于它完全是模块化的。您始终可以创建自己的配置提供程序并实现您想要的任何内容。例如,您可以编写一个实际 支持加密的JSON提供程序,如果这是您想要的方式。
答案 1 :(得分:2)
请记住,不要将秘密存储在网站中的主appsettings.json
中,并且通常保存在源代码管理中。使用文件提供程序在服务器上的其他位置找到该文件。
如果您有权访问Azure,则可以将密码存储在Azure Key Vault而不是appsettings.json
。
考虑到这一点,如果您想使用JSON文件,可以使用桥接器或代理类来处理值的解密。
首先,您需要一个类来解密这些值。为简洁起见,我不会在此处详细介绍解密类,并假设已经编写了一个名为SettingsDecryptor
的类,并使用单个方法Decrypt实现了一个名为ISettingsDecryptor
的接口,该方法解密了字符串值。
桥类有两个构造函数参数。
IOptions<T>
或IOptionsSnapshot<T>
,其中T是appsettings.json
中的部分通过services.Configure
方法绑定的类(例如MyAppSettings
)。或者,如果您不想绑定到类,则可以使用IConfiguration
代替直接从配置中读取。ISettingsDecryptor
的解密类。在桥类中,需要解密的每个属性都应该使用解密类来解密配置中的加密值。
public class MyAppSettingsBridge : IAppSettings
{
private readonly IOptions<MyAppSettings> _appSettings;
private readonly ISettingsDecrypt _decryptor;
public MyAppSettingsBridge(IOptionsSnapshot<MyAppSettings> appSettings, ISettingsDecrypt decryptor) {
_appSettings = appSettings ?? throw new ArgumentNullException(nameof(appSettings));
_decryptor = decryptor ?? throw new ArgumentException(nameof(decryptor));
}
public string ApplicationName => _appSettings.Value.ApplicationName;
public string SqlConnectionSting => _decryptor.Decrypt(_appSettings.Value.Sql);
public string OracleConnectionSting => _decryptor.Decrypt(_appSettings.Value.Oracle);
}
DI容器应该设置如下:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddOptions();
services.Configure<MyAppSettings>(Configuration.GetSection("MyAppSettings"));
services.AddSingleton(Configuration);
services.AddSingleton<ISettingsDecrypt, SettingsDecryptor>();
services.AddScoped<IAppSettings, MyAppSettingsBridge>();
}
然后,控制器可以有一个构造函数,将桥接器作为IAppSettings
来访问解密的设置。
上面的答案是整体解决方案的简要总结,因为需要相当多的代码。
完整的详细说明可以在我的博文Hiding Secrets in appsettings.json
– Using a Bridge in your ASP.Net Core Configuration (Part 4)中看到,其中我详细介绍了使用桥接模式。在https://github.com/configureappio/ConfiguarationBridgeCrypto
答案 2 :(得分:1)
对于ASP.NET Core,最佳解决方案是在应用程序启动时对配置值进行任何转换,例如解密或字符串替换。这就是配置提供程序存在的原因。
可以将配置提供程序链接在一起。在Microsoft.Extensions.Configuration的源代码中,有一个名为ChainedConfigurationProvider的类可以用作示例。
GLFW_OPENGL_CORE_PROFILE
如果您使用的是Docker Swarm或Kubernetes,则无需加密appsettings.json文件中的密码。您可以使用内置的Key-per-file Configuration Provider或自定义配置提供程序从Docker机密读取密码并将其映射到配置值。
在我的博客文章How to manage passwords in ASP.NET Core configuration files上,我详细解释了如何创建自定义配置提供程序,该提供程序允许您仅将密码保密,并在运行时更新配置字符串。另外,本文的完整源代码也托管在github.com/gabihodoroaga/blog-app-secrets上。
答案 3 :(得分:1)
您可以看一下我的Moonrise.StandardUtils.NetStd NuGet软件包。 Settings类具有透明的加密/解密,并且是访问JSON设置文件(无论是Application还是User)的一种简单得多的方法。在任何.Net应用程序中。
Settings.Application.SettingsEncryptor = new DpApiSettingsEncryptor(DpApiSettingsEncryptor.ProtectionScope.Machine);
MyConfigClass config;
Settings.Application.Read("Configuration", ref config)
任何先前加密的个人或一组设置都将被解密。您可以使用以下方式加密设置:
Settings.Application.Write("ContainerStartup:FileProviders:BrandingConfig", secretValue, true);
或者使用捆绑在Moonrise.Microsoft.EncryptedJsonConfiguration或Moonrise.Samples NuGet软件包中的EncryptAppSettings.exe-您将在软件包文件/目录中找到它-这是一种获取.exe文件的方法。民间。
Moonrise.Microsoft.EncryptedJsonConfiguration允许您将IConfigurationBuilder与.AddEncyptedJsonFile(...)一起使用,然后将透明解密使用EncryptAppSettings.exe加密的所有设置。
这是部分加密的appSettings.json的一部分
"ContainerStartup": {
"FileProviders": {
"BrandingConfig": "[{ENC]{AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAsevacb5DdkaxvzOPPkLrdwQAAAACAAAAAAAQZgAAAAEAACAAAADITnvKp+Lnb5n6kPK7WyYuWFQLnbvbkOvgHBLBdIw2MAAAAAAOgAAAAAIAACAAAADqJZ0YUGC+jOEr4/6hgQ+8UdZ1ssbiEXXCjdhSV3teZ3AAAAAW4d8Z38JYNM1Dw45KquZYK+bTszYp/1wXt+LiYpiy2q88sOpQr5VpDFatgWar1aOePXA52RC6eZH1HFrYijqWTSEiffBqWzWZPPTXw1wkUVB5MLIjOq4bu33h+4Z23Vy+XaFsf6IFVl4ccM4fHpsRQAAAAAG5OP+nJQxzH3A7n3gnh8d2eAOFgLWzYCDgQon7NXHeEJcZezgxT+0npvIQ/kcYb1Xpwt7FiNtyJ2HZswL8MSg=]{ENC[{",
"SearchingNotification": true,
"UseBranding": false,
"UseLocalModule": true,
"UseLocalModuleEmbedded": true,
"UseParentModules": true,
"UseParentModulesEmbedded": false
},
答案 4 :(得分:0)
您可以使用Secret Manager工具,而不是将敏感数据存储在您无法加密的json文件中。这是full documentation。
编辑:从安全角度来看,它仅适用于开发目的。