在 ASP.NET Core 中存放的密钥加密Key encryption at rest in ASP.NET Core

本文内容

默认情况下,数据保护系统使用发现机制来确定应如何对加密密钥进行静态加密。开发人员可以重写发现机制,并手动指定密钥的加密方式。

警告

如果指定显式密钥持久性位置,数据保护系统将注销静态密钥加密机制。因此,不再静态加密密钥。建议为生产部署指定显式密钥加密机制本主题介绍了静态加密机制选项。

Azure Key VaultAzure Key Vault

若要在Azure Key Vault中存储密钥,请在 Startup 类中配置ProtectKeysWithAzureKeyVault的系统:

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddDataProtection()
  4. .PersistKeysToAzureBlobStorage(new Uri("<blobUriWithSasToken>"))
  5. .ProtectKeysWithAzureKeyVault("<keyIdentifier>", "<clientId>", "<clientSecret>");
  6. }

有关详细信息,请参阅Configure ASP.NET Core Data Protection: ProtectKeysWithAzureKeyVault

Windows DPAPIWindows DPAPI

仅适用于 Windows 部署。

使用 Windows DPAPI 时,将使用CryptProtectData对密钥材料进行加密,然后将其保存到存储中。DPAPI 是一种适用于从不在当前计算机之外读取的数据的适当加密机制(尽管可以将这些密钥备份到 Active Directory; 请参阅DPAPI 和漫游配置文件)。若要配置 DPAPI 静态密钥加密,请调用ProtectKeysWithDpapi扩展方法之一:

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. // Only the local user account can decrypt the keys
  4. services.AddDataProtection()
  5. .ProtectKeysWithDpapi();
  6. }

如果在没有参数的情况下调用 ProtectKeysWithDpapi,则只有当前的 Windows 用户帐户才能解密持久的密钥环。您可以选择指定计算机上的任何用户帐户(而不只是当前用户帐户)能够破译密钥环:

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. // All user accounts on the machine can decrypt the keys
  4. services.AddDataProtection()
  5. .ProtectKeysWithDpapi(protectToLocalMachine: true);
  6. }

X.509 证书X.509 certificate

如果应用分布在多台计算机上,则在计算机上分发共享的 x.509 证书,并将托管应用配置为使用证书进行静态密钥加密可能会很方便。

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddDataProtection()
  4. .ProtectKeysWithCertificate("3BCE558E2AD3E0E34A7743EAB5AEA2A9BD2575A0");
  5. }

由于 .NET Framework 限制,仅支持具有 CAPI 私钥的证书。请参阅下面的内容,了解这些限制的可能解决方法。

Windows DPAPI-NGWindows DPAPI-NG

此机制仅在 Windows 8/Windows Server 2012 或更高版本上可用。

从 Windows 8 开始,Windows OS 支持 DPAPI-NG (也称为 CNG DPAPI)。有关详细信息,请参阅关于 CNG DPAPI

主体编码为保护描述符规则。在以下调用ProtectKeysWithDpapiNG的示例中,只有具有指定 SID 的已加入域的用户才能解密密钥环:

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. // Uses the descriptor rule "SID=S-1-5-21-..."
  4. services.AddDataProtection()
  5. .ProtectKeysWithDpapiNG("SID=S-1-5-21-...",
  6. flags: DpapiNGProtectionDescriptorFlags.None);
  7. }

还有 ProtectKeysWithDpapiNG的无参数重载。使用此简便方法指定规则 "SID = {CURRENTACCOUNT_SID}",其中_CURRENT_ACCOUNT_SID是当前 Windows 用户帐户的 SID:

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. // Use the descriptor rule "SID={current account SID}"
  4. services.AddDataProtection()
  5. .ProtectKeysWithDpapiNG();
  6. }

在此方案中,AD 域控制器负责分发由 DPAPI-NG 操作使用的加密密钥。目标用户可以从任何已加入域的计算机(前提是进程在其标识下运行)解密已加密的有效负载。

基于证书的加密和 Windows DPAPI-NGCertificate-based encryption with Windows DPAPI-NG

如果应用在 Windows 8.1/Windows Server 2012 R2 或更高版本上运行,则可以使用 Windows DPAPI-NG 执行基于证书的加密。使用规则描述符字符串 "CERTIFICATE = HashId: THUMBPRINT",其中THUMBPRINT是证书的十六进制编码的 SHA1 指纹:

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddDataProtection()
  4. .ProtectKeysWithDpapiNG("CERTIFICATE=HashId:3BCE558E2...B5AEA2A9BD2575A0",
  5. flags: DpapiNGProtectionDescriptorFlags.None);
  6. }

指向此存储库的任何应用都必须在 Windows 8.1/Windows Server 2012 R2 或更高版本上运行,才能解密密钥。

自定义密钥加密Custom key encryption

如果不适合使用机箱内机制,开发人员可以通过提供自定义IXmlEncryptor来指定其自己的密钥加密机制。