它说“如果未配置数据保护,密钥将保存在内存中并在应用程序重新启动时丢弃。”,我不希望发生这种情况,因此我配置了数据startup.cs 中的保护:
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"PATH-HERE"))
当我启动应用程序进行测试时,日志中显示一条警告:No XML encryptor configured. Key {GUID} may be persisted to storage in unencrypted form.
。
我发现我需要使用 ProtectKeysWith*
来加密密钥。但是因为我试图将应用程序发布到 Linux 服务器,所以我不能使用 ProtectKeysWithDpapi
或 ProtectKeysWithDpapiNG
(因为它们只能在 Windows 服务器上使用),所以剩下的唯一选项是 {{1 }}。
基本上,我做了一些搜索,我发现我可以使用这些命令来创建自签名 X.509
证书:
X.509
我可以像这样在启动时添加这个证书:
"C:\Program Files\Git\usr\bin\openssl.exe" genrsa -out private.key 2048
"C:\Program Files\Git\usr\bin\openssl.exe" req -new -x509 -key private.key -out publickey.cer -days 2000
"C:\Program Files\Git\usr\bin\openssl.exe" pkcs12 -export -out idp.pfx -inkey private.key -in publickey.cer
所以我的问题是我什至需要加密密钥吗?如果我应该这样做,我的解决方案是否有效?我可以在生产中使用这个解决方案而没有任何问题吗? (请记住,我将为我的应用使用 Linux 服务器)
更新 1: 我在 StackOverflow 问题中做了更多的挖掘,我发现了这一点: https://stackoverflow.com/a/48867984/14951696。
显然,只要您在内部使用自签名证书(就像我在做的那样)就可以了。我会在发布我的应用后再次更新,以防有人有同样的问题。
更新 2: 我决定使用 Windows 服务器,我发现使用自签名证书加密密钥没有问题。如果有什么事情我会再次更新。
答案 0 :(得分:0)
我的两分钱,不知道你发现的问题是什么,如果没有,你可以给我们下面的解决方案。
为了拥有共享的数据保护密钥,需要明确执行它。 需要注意的是,在启动时密钥不存在于源中,它是与过期相关联的。想法是将 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; }
}
存储库,可以是数据库,文件系统,云存储,任何适合你的,实现你喜欢的波纹接口
public interface IDataProtectionRepo
{
IEnumerable<ProtectionKeyModel> GetAll();
void AddOrUpdate(ProtectionKeyModel protectionKeyModel);
}