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

时间:2021-01-06 12:29:45

标签: asp.net-core data-protection

在这个链接中: https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-5.0#data-protection

它说“如果未配置数据保护,密钥将保存在内存中并在应用程序重新启动时丢弃。”,我不希望发生这种情况,因此我配置了数据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 服务器,所以我不能使用 ProtectKeysWithDpapiProtectKeysWithDpapiNG(因为它们只能在 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 服务器,我发现使用自签名证书加密密钥没有问题。如果有什么事情我会再次更新。

1 个答案:

答案 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);
    }