asp.net核心数据保护密钥加密



在此链接中:https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-5.0#数据保护

上面写着"strong";如果未配置数据保护,则密钥将保存在内存中,并在应用程序重新启动时丢弃",我不希望发生这种情况,所以我在启动时配置了数据保护.cs:

services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"PATH-HERE"))

当我启动应用程序进行测试时,日志中会显示一条警告:No XML encryptor configured. Key {GUID} may be persisted to storage in unencrypted form.

我发现我需要使用ProtectKeysWith*来加密密钥。但因为我正试图将应用程序发布到Linux服务器,所以我无法使用ProtectKeysWithDpapiProtectKeysWithDpapiNG(因为它们只能在Windows服务器上使用(,所以剩下的唯一选项是X.509

基本上,我做了一些搜索,发现我可以使用这些命令创建一个自签名的X.509证书:

"C:Program FilesGitusrbinopenssl.exe" genrsa -out private.key 2048
"C:Program FilesGitusrbinopenssl.exe" req -new -x509 -key private.key -out publickey.cer -days 2000
"C:Program FilesGitusrbinopenssl.exe" pkcs12 -export -out idp.pfx -inkey private.key -in publickey.cer

我可以在启动时添加这个证书,如下所示:

services
.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"PATH-TO-SAVE-KEYS"))
.SetDefaultKeyLifetime(new TimeSpan(90, 0, 0, 0, 0))
.SetApplicationName("APPNAME-HERE")
.ProtectKeysWithCertificate(new X509Certificate2(@"CERTIFICATE-PATH", "CERTIFICATE-PASSWORD"));

所以我的问题是,我甚至需要加密密钥吗?如果我应该,我的解决方案有效吗?我能在生产中毫无问题地使用这种解决方案吗?(请记住,我将为我的应用程序使用Linux服务器(

更新1:我在StackOverflow问题上做了更多的挖掘,发现了以下内容:https://stackoverflow.com/a/48867984/14951696.

显然,只要你在内部使用自签名证书(就像我所做的那样(就可以了。我会在发布应用程序后再次更新,以防有人有同样的问题。

更新2:我决定使用Windows服务器,并且我发现使用自签名证书加密密钥没有问题。如果发生任何事情,我会再次更新。

我的两分钱,不知道你发现了什么问题,如果不知道,你可以给我们下面的解决方案。

为了拥有共享的数据保护密钥,需要显式地强制执行它。需要注意的是,在启动时,is键不存在于创建的源中,并与过期时间关联。Ideea将XElement及其名称保存在存储中,该存储可用于在启动时检索该值。

启动时:

services.Configure<KeyManagementOptions>(options =>
{
IDataProtectionRepo dataProtection = services.BuildServiceProvider().GetRequiredService<IDataProtectionRepo>();
options.NewKeyLifetime = DateTime.Now.AddYears(10) - DateTime.Now; // new one is created
options.XmlRepository = new DataProtectionKeyRepository(dataProtection);
});

其中DataProtectionKeyRepository是IXmlRepository 的实现

public class DataProtectionKeyRepository : IXmlRepository
{

private IDataProtectionRepo dataProtectionRepo;
public DataProtectionKeyRepository(IDataProtectionRepo dataProtectionRepo)
{
this.dataProtectionRepo = dataProtectionRepo;
}
public IReadOnlyCollection<XElement> GetAllElements()
{
return new ReadOnlyCollection<XElement>(dataProtectionRepo.GetAll().Select(k => XElement.Parse(k.XmlData)).ToList());
}
public void StoreElement(XElement element, string friendlyName)
{
dataProtectionRepo.AddOrUpdate(new ProtectionKeyModel { Name = friendlyName, XmlData = element.ToString() });
}
}

通信类

public class ProtectionKeyModel
{
public string Name { get; set; }
public string XmlData { get; set; }
}

而存储回购,可以是DB、文件系统、云存储,任何对你来说合适的,都可以按照你喜欢的方式实现下面的接口

public interface IDataProtectionRepo
{
IEnumerable<ProtectionKeyModel> GetAll();
void AddOrUpdate(ProtectionKeyModel protectionKeyModel);
}

最新更新