首页 > 解决方案 > ASP.NET Core 应用程序无法解密持久保存到注册表的受保护数据

问题描述

我在 .NET5 上使用 DataProtection 来保护我正在使用我的应用程序生成的 JWT 的密钥。密钥是在安装时通过使用特殊参数启动我的应用程序的 .exe 版本来编写的——它获取密钥、保护它并将其写入文件。当 Web 应用程序在 IIS 上启动时,它会在 JWT 发布过程中取消对该文件内容的保护。

这是我启动 exe 时发生的情况

var serviceCollection = new ServiceCollection();
serviceCollection
    .AddDataProtection(o => o.ApplicationDiscriminator = applicationDiscriminator);
    .SetApplicationName(appName)
    .PersistKeysToRegistry(Microsoft.Win32.Registry.CurrentUser.CreateSubKey(registryLocation, true));
    
var services = serviceCollection.BuildServiceProvider();
var dataProtectionProvider = services.GetService<IDataProtectionProvider>();
var protector = dataProtectionProvider.CreateProtector(appName);    
var protectedSecret = protector.Protect(plaintextKey);
//write content to a file

我 Startup.cs / ConfigureServices,我为 DI 设置数据保护如下

services
    .AddDataProtection(o => { o.ApplicationDiscriminator = applicationDiscriminator; })
    .SetApplicationName(appName)
    .PersistKeysToRegistry(Microsoft.Win32.Registry.CurrentUser.CreateSubKey(registryLocation, true));

然后当应用程序启动并运行时,我得到如下密钥

public class KeyReader
{
    private IDataProtectionProvider dataProtectionProvider;

    public KeyReader(IDataProtectionProvider dataProtectionProvider) 
    {
        this.dataProtectionProvider = dataProtectionProvider;
    }
    
    public String ReadKey(string fileName)
    {
        var fileContent = File.ReadAll(fileName);
        return dataProtectionProvider.Unprotect(fileContent)
    }
}

现在,当我的应用程序在 IIS 上下文中启动时(它在应用程序池上运行,该应用程序池运行在与我在保护密钥时启动 .exe 相同的用户身份下),它无法取消保护文件内容。

我得到的确切错误是The provided payload cannot be decrypted because it was not protected with this protection provider.

如果我更改要使用的代码PersistKeysToFileSystem(还没有尝试过 DAPI 保护它们),它就可以工作。那么有什么不同呢?

我也尝试不使用这些PersistKeysTo..选项,在这种情况下我得到了 The key {some guid here} was not found in the key ring.(当然,对于每个测试,我都会重新生成我保存密钥的文件,并始终在与应用程序池相同的帐户下执行该操作帐户)。当然,我也参加Provision-AutoGenKeys.ps1了没有 的测试PersistKeysTo...,但它只是没有。在没有手动密钥持久性的情况下,如果我查看调试日志Microsoft.AspNetCore.DataProtection,它会在我作为 exe 启动它时从另一个位置获取密钥材料,而不是当应用程序在 IIS 上运行时(这给了我尝试指定我自己的密钥的想法坚持)。

关于如何使用注册表或理想情况下根本不必指定手动密钥持久性来完成这项工作的任何想法?

标签: c#asp.net-coredata-protection

解决方案


推荐阅读