负载均衡环境下如何使用DPAPI

信息安全 加密 Web应用程序 密钥管理 。网
2021-08-22 17:20:25



DPAPI 可用于加密机密数据。
我们打算在我们的网络应用程序中使用它来加密一些数据并将加密的数据存储在数据库中。当需要时,我们解密数据并将它们呈现在 UI(网页)上。如果我们将 Web 应用程序托管在单个 Web 服务器上,效果会很好。但是当我们将其迁移到负载平衡环境时,问题就出现了——将 Web 应用程序托管在多个 Web 服务器上。因为应用程序无法解密在另一台机器上加密的数据。

我们参考了一些来自互联网的信息,看起来我们需要配置一个漫游用户帐户并使用该帐户运行应用程序池。

我们要使用 DPAPI 的原因是它不会涉及对密钥的额外管理工作。

有没有类似的经历,请问你是怎么解决的?或者其他一些建议?

2个回答

您应该对设置进行两项相对较小的更改。

首先,您应该始终使用 DPAPI USER_MODE,这是 DPAPI 方法的参数。
和类的.Protect()方法需要一个额外的范围参数,这应该设置为forfor ,具体取决于您使用的。)(如果您直接调用 WINAPI 函数,我希望您没有使用,您也可以直接发送参数。哦,用.NET类代替。)ProtectedDataProtectedMemoryDataProtectionScope.CurrentUserProtectedDataMemoryProtectionScope.SameLogonProtectedMemoryUSER_MODE

其次,您应该使用 DPAPI 类来加密您的加密密钥——而不是直接加密数据。
换句话说,您生成一个加密密钥,将其分发给您的所有服务器,并让它们通过 DPAPI 存储密钥。(是的,您可能需要一个小型实用程序。)
这将使任何密钥管理过程更加容易,密钥是共享的,因此解密更容易,并且它仍然受到 DPAPI 加密的保护。

八年后。. . 您可以尝试使用CNG DPAPI,它适用于可能会或可能不会负载平衡的云环境。从该链接(以防它被删除):

Microsoft 在 Windows 2000 中引入了数据保护应用程序编程接口 (DPAPI)。该 API 由两个函数组成,CryptProtectData 和 CryptUnprotectData。DPAPI 是 CryptoAPI 的一部分,适用于对使用密码学知之甚少的开发人员。这两个函数可用于加密和解密单台计算机上的静态数据。

然而,云计算通常要求在一台计算机上加密的内容在另一台计算机上解密。因此,从 Windows 8 开始,Microsoft 将使用相对简单的 API 的想法扩展到涵盖云场景。这种称为 DPAPI-NG 的新 API 使您能够安全地共享机密(密钥、密码、密钥材料)和消息,方法是将它们保护到一组主体,这些主体可用于在适当的身份验证和授权后在不同的计算机上取消保护它们。

在 .NET Core 中,这看起来像

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .ProtectKeysWithDpapiNG();
}

更新

我喜欢使用实体框架 (EF) + CNG-DPAPI。在 .NET Core 中,您可以使用 EF 创建“键”上下文。首先将 appsettings.json 文件中的连接字符串添加到您将存储密钥的 SQL 数据库。在本例中,我们称其为“MyKeysConnection”。

{
    "ConnectionStrings": {
        "MyKeysConnection": "Server=XXX;Database=YYY;"
    }
}

接下来在您的项目中创建一个类,如下所示:

class MyKeysContext : DbContext, IDataProtectionKeyContext
{
    // A recommended constructor overload when using EF Core 
    // with dependency injection.
    public MyKeysContext(DbContextOptions<MyKeysContext> options) 
        : base(options) { }

    // This maps to the table that stores keys.
    public DbSet<DataProtectionKey> DataProtectionKeys { get; set; }
}

然后在 Visual Studio 的包管理器控制台中,键入Script-Migration -Context MyKeysContext以获取可以在 SSMS 中运行的脚本,该脚本将为您创建存储密钥的表。最后更新我在上面发布的 Startup.cs 文件中的代码,如下所示:

public void ConfigureServices(IServiceCollection services)
{
    // Add a DbContext to store your Database Keys
    services.AddDbContext<MyKeysContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("MyKeysConnection")));

    services.AddDataProtection()
        .PersistKeysToDbContext<MyKeysContext>()
        .ProtectKeysWithDpapiNG();
}

有关此方法的更多信息,请参见此处