配置 ASP.NET Core 数据保护Configure ASP.NET Core Data Protection

初始化数据保护系统时,它适用默认设置基于操作环境。When the Data Protection system is initialized, it applies default settings based on the operational environment. 这些设置通常适用于一台计算机上运行的应用。These settings are generally appropriate for apps running on a single machine. 有一名开发人员可能想要更改默认设置的情况:There are cases where a developer may want to change the default settings:

  • 应用程序分布在多台计算机。The app is spread across multiple machines.
  • 出于合规性原因。For compliance reasons.

对于这些情况下,数据保护系统提供了丰富的配置 API。For these scenarios, the Data Protection system offers a rich configuration API.

警告

类似于配置文件,数据保护密钥环应受到保护使用适当的权限。Similar to configuration files, the data protection key ring should be protected using appropriate permissions. 可以选择加密密钥的静态,但这不会阻止攻击者创建新的密钥。You can choose to encrypt keys at rest, but this doesn't prevent attackers from creating new keys. 因此,应用程序的安全将受到影响。Consequently, your app's security is impacted. 使用数据保护配置的存储位置应具有其访问仅限于应用本身会保护配置文件的方式类似。The storage location configured with Data Protection should have its access limited to the app itself, similar to the way you would protect configuration files. 例如,如果您选择将密钥环存储在磁盘上,使用文件系统权限。For example, if you choose to store your key ring on disk, use file system permissions. 请确保仅下的标识该 web 应用将在运行具有读取、 写入和创建权限访问此目录。Ensure only the identity under which your web app runs has read, write, and create access to that directory. 如果使用 Azure Blob 存储,只有 web 应用程序应能够读取、 写入或创建新的条目中的 blob 存储区,等等。If you use Azure Blob Storage, only the web app should have the ability to read, write, or create new entries in the blob store, etc.

扩展方法AddDataProtection返回IDataProtectionBuilderThe extension method AddDataProtection returns an IDataProtectionBuilder. IDataProtectionBuilder 显示扩展方法,您可以链接在一起以配置数据保护选项。IDataProtectionBuilder exposes extension methods that you can chain together to configure Data Protection options.

ProtectKeysWithAzureKeyVaultProtectKeysWithAzureKeyVault

若要将密钥存储在Azure 密钥保管库,配置与系统ProtectKeysWithAzureKeyVaultStartup类:To store keys in Azure Key Vault, configure the system with ProtectKeysWithAzureKeyVault in the Startup class:

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

设置密钥环存储位置 (例如, PersistKeysToAzureBlobStorage)。Set the key ring storage location (for example, PersistKeysToAzureBlobStorage). 必须设置位置,因为在调用ProtectKeysWithAzureKeyVault实现IXmlEncryptor禁用自动数据保护设置,包括密钥环存储位置。The location must be set because calling ProtectKeysWithAzureKeyVault implements an IXmlEncryptor that disables automatic data protection settings, including the key ring storage location. 前面的示例中使用 Azure Blob 存储来持久保存密钥环。The preceding example uses Azure Blob Storage to persist the key ring. 有关详细信息,请参阅密钥存储提供程序:Azure 存储For more information, see Key storage providers: Azure Storage. 您还可以保留使用本地密钥环PersistKeysToFileSystemYou can also persist the key ring locally with PersistKeysToFileSystem.

keyIdentifier是用于密钥加密的密钥保管库密钥标识符。The keyIdentifier is the key vault key identifier used for key encryption. 例如,名为 key vault 中创建的密钥dataprotectioncontosokeyvault具有密钥标识符https://contosokeyvault.vault.azure.net/keys/dataprotection/For example, a key created in key vault named dataprotection in the contosokeyvault has the key identifier https://contosokeyvault.vault.azure.net/keys/dataprotection/. 提供应用程序与Unwrap KeyWrap Key对密钥保管库的权限。Provide the app with Unwrap Key and Wrap Key permissions to the key vault.

ProtectKeysWithAzureKeyVault 重载:ProtectKeysWithAzureKeyVault overloads:

PersistKeysToFileSystemPersistKeysToFileSystem

若要将密钥存储在 UNC 共享而不是在 %LOCALAPPDATA% 的默认位置,配置与系统PersistKeysToFileSystem:To store keys on a UNC share instead of at the %LOCALAPPDATA% default location, configure the system with PersistKeysToFileSystem:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"));
}

警告

如果更改密钥持久性位置时,系统将不再会自动加密静态情况下,密钥由于它不知道是否 DPAPI 是一种合适的加密机制。If you change the key persistence location, the system no longer automatically encrypts keys at rest, since it doesn't know whether DPAPI is an appropriate encryption mechanism.

ProtectKeysWith*ProtectKeysWith*

您可以将系统配置为通过调用的任何保护静态密钥ProtectKeysWith* 配置 Api。You can configure the system to protect keys at rest by calling any of the ProtectKeysWith* configuration APIs. 请考虑下面的示例,它将密钥存储的 UNC 共享上并对这些密钥在使用特定的 X.509 证书的其余部分进行加密:Consider the example below, which stores keys on a UNC share and encrypts those keys at rest with a specific X.509 certificate:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"))
        .ProtectKeysWithCertificate("thumbprint");
}

在 ASP.NET Core 2.1 或更高版本,可以提供X509Certificate2ProtectKeysWithCertificate,例如从文件加载证书:In ASP.NET Core 2.1 or later, you can provide an X509Certificate2 to ProtectKeysWithCertificate, such as a certificate loaded from a file:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"))
        .ProtectKeysWithCertificate(
            new X509Certificate2("certificate.pfx", "password"));
}

请参阅密钥静态加密的更多示例和讨论的内置密钥加密机制。See Key Encryption At Rest for more examples and discussion on the built-in key encryption mechanisms.

UnprotectKeysWithAnyCertificateUnprotectKeysWithAnyCertificate

在 ASP.NET Core 2.1 或更高版本,可以轮换证书和解密密钥使用一个数组静止X509Certificate2证书与UnprotectKeysWithAnyCertificate:In ASP.NET Core 2.1 or later, you can rotate certificates and decrypt keys at rest using an array of X509Certificate2 certificates with UnprotectKeysWithAnyCertificate:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"))
        .ProtectKeysWithCertificate(
            new X509Certificate2("certificate.pfx", "password"));
        .UnprotectKeysWithAnyCertificate(
            new X509Certificate2("certificate_old_1.pfx", "password_1"),
            new X509Certificate2("certificate_old_2.pfx", "password_2"));
}

SetDefaultKeyLifetimeSetDefaultKeyLifetime

若要配置系统而不是默认值 90 天使用的密钥生存期为 14 天,请使用SetDefaultKeyLifetime:To configure the system to use a key lifetime of 14 days instead of the default 90 days, use SetDefaultKeyLifetime:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .SetDefaultKeyLifetime(TimeSpan.FromDays(14));
}

SetApplicationNameSetApplicationName

默认情况下,数据保护系统隔离应用中的另一个基于其内容根路径,即使它们共享同一个物理密钥存储库。By default, the Data Protection system isolates apps from one another based on their content root paths, even if they're sharing the same physical key repository. 这可以防止应用程序了解彼此的受保护的负载。This prevents the apps from understanding each other's protected payloads.

若要共享受保护的应用之间的有效负载:To share protected payloads among apps:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .SetApplicationName("shared app name");
}

DisableAutomaticKeyGenerationDisableAutomaticKeyGeneration

您可能不希望应用程序以自动滚动更新的密钥 (创建新的密钥),因为它们接近过期的方案。You may have a scenario where you don't want an app to automatically roll keys (create new keys) as they approach expiration. 这一个示例可能是应用设置中的主/辅助关系,其中只有主应用程序负责密钥管理问题,然后辅助应用程序只需将密钥环的只读视图。One example of this might be apps set up in a primary/secondary relationship, where only the primary app is responsible for key management concerns and secondary apps simply have a read-only view of the key ring. 可以将辅助应用程序配置为将视为只读密钥环,通过配置具有系统DisableAutomaticKeyGeneration:The secondary apps can be configured to treat the key ring as read-only by configuring the system with DisableAutomaticKeyGeneration:

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

每个应用程序隔离Per-application isolation

数据保护系统提供了 ASP.NET Core 主机,但它自动隔离了从另一个,应用程序,即使这些应用在相同的工作进程帐户下运行,并且使用相同的主密钥材料。When the Data Protection system is provided by an ASP.NET Core host, it automatically isolates apps from one another, even if those apps are running under the same worker process account and are using the same master keying material. 这是某种程度上类似于 IsolateApps 修饰符将来自 System.Web 的<machineKey>元素。This is somewhat similar to the IsolateApps modifier from System.Web's <machineKey> element.

隔离机制的工作方式考虑在本地计算机上的每个应用使用作为唯一的租户,因此是IDataProtector取得 root 权限的任何给定的应用会自动包括用作鉴别器的应用程序 ID。The isolation mechanism works by considering each app on the local machine as a unique tenant, thus the IDataProtector rooted for any given app automatically includes the app ID as a discriminator. 应用程序的唯一 ID 是应用的物理路径:The app's unique ID is the app's physical path:

  • 对于在 IIS 中承载的应用程序,唯一的 ID 是应用程序的 IIS 物理路径。For apps hosted in IIS, the unique ID is the IIS physical path of the app. 如果在 web 场环境中部署应用,则此值是稳定,假定 web 场中的所有计算机上的 IIS 环境配置方式都类似。If an app is deployed in a web farm environment, this value is stable assuming that the IIS environments are configured similarly across all machines in the web farm.
  • 对于自承载的应用上运行Kestrel 服务器,唯一的 ID 是磁盘上的应用程序的物理路径。For self-hosted apps running on the Kestrel server, the unique ID is the physical path to the app on disk.

唯一标识符设计可以经受住重置—的单个应用程序和计算机本身。The unique identifier is designed to survive resets—both of the individual app and of the machine itself.

此隔离机制假设应用程序不是恶意。This isolation mechanism assumes that the apps are not malicious. 恶意应用程序始终会影响在相同的工作进程帐户下运行的任何其他应用。A malicious app can always impact any other app running under the same worker process account. 在共享宿主环境中应用是相互不受信任,托管提供商应采取措施来确保应用程序,包括分离应用的基础密钥存储库之间的 OS 级别隔离。In a shared hosting environment where apps are mutually untrusted, the hosting provider should take steps to ensure OS-level isolation between apps, including separating the apps' underlying key repositories.

如果由 ASP.NET Core 主机未提供数据保护系统 (例如,如果通过其实例化DataProtectionProvider具体类型) 应用程序隔离在默认情况下处于禁用状态。If the Data Protection system isn't provided by an ASP.NET Core host (for example, if you instantiate it via the DataProtectionProvider concrete type) app isolation is disabled by default. 只要它们提供相应由相同的密钥材料提供支持的所有应用程序时禁用应用程序隔离,可以共享负载目的When app isolation is disabled, all apps backed by the same keying material can share payloads as long as they provide the appropriate purposes. 若要提供应用隔离在此环境中的,调用SetApplicationName方法的配置对象,并提供每个应用的唯一名称。To provide app isolation in this environment, call the SetApplicationName method on the configuration object and provide a unique name for each app.

更改算法与 UseCryptographicAlgorithmsChanging algorithms with UseCryptographicAlgorithms

数据保护堆栈可以更改使用新生成的键的默认算法。The Data Protection stack allows you to change the default algorithm used by newly-generated keys. 若要执行此操作的最简单方法是调用UseCryptographicAlgorithms从配置回调:The simplest way to do this is to call UseCryptographicAlgorithms from the configuration callback:

services.AddDataProtection()
    .UseCryptographicAlgorithms(
        new AuthenticatedEncryptorConfiguration()
    {
        EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
        ValidationAlgorithm = ValidationAlgorithm.HMACSHA256
    });
services.AddDataProtection()
    .UseCryptographicAlgorithms(
        new AuthenticatedEncryptionSettings()
    {
        EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
        ValidationAlgorithm = ValidationAlgorithm.HMACSHA256
    });

默认的 EncryptionAlgorithm AES-256-CBC,且默认 ValidationAlgorithm 是 HMACSHA256。The default EncryptionAlgorithm is AES-256-CBC, and the default ValidationAlgorithm is HMACSHA256. 可以由系统管理员通过设置默认策略计算机范围的策略,但显式调用UseCryptographicAlgorithms重写默认策略。The default policy can be set by a system administrator via a machine-wide policy, but an explicit call to UseCryptographicAlgorithms overrides the default policy.

调用UseCryptographicAlgorithms,可指定预定义的内置列表中的所需的算法。Calling UseCryptographicAlgorithms allows you to specify the desired algorithm from a predefined built-in list. 无需担心有关算法的实现。You don't need to worry about the implementation of the algorithm. 在上述方案中,数据保护系统尝试使用 AES 的 CNG 实现,如果在 Windows 上运行。In the scenario above, the Data Protection system attempts to use the CNG implementation of AES if running on Windows. 否则,它将回退到托管System.Security.Cryptography.Aes类。Otherwise, it falls back to the managed System.Security.Cryptography.Aes class.

您可以手动指定通过调用实现UseCustomCryptographicAlgorithmsYou can manually specify an implementation via a call to UseCustomCryptographicAlgorithms.

提示

更改算法不会影响密钥环中的现有密钥。Changing algorithms doesn't affect existing keys in the key ring. 它只影响新生成的键。It only affects newly-generated keys.

指定托管的自定义算法Specifying custom managed algorithms

若要指定托管的自定义算法,创建ManagedAuthenticatedEncryptorConfiguration指向实现类型的实例:To specify custom managed algorithms, create a ManagedAuthenticatedEncryptorConfiguration instance that points to the implementation types:

serviceCollection.AddDataProtection()
    .UseCustomCryptographicAlgorithms(
        new ManagedAuthenticatedEncryptorConfiguration()
    {
        // A type that subclasses SymmetricAlgorithm
        EncryptionAlgorithmType = typeof(Aes),

        // Specified in bits
        EncryptionAlgorithmKeySize = 256,

        // A type that subclasses KeyedHashAlgorithm
        ValidationAlgorithmType = typeof(HMACSHA256)
    });

若要指定托管的自定义算法,创建ManagedAuthenticatedEncryptionSettings指向实现类型的实例:To specify custom managed algorithms, create a ManagedAuthenticatedEncryptionSettings instance that points to the implementation types:

serviceCollection.AddDataProtection()
    .UseCustomCryptographicAlgorithms(
        new ManagedAuthenticatedEncryptionSettings()
    {
        // A type that subclasses SymmetricAlgorithm
        EncryptionAlgorithmType = typeof(Aes),

        // Specified in bits
        EncryptionAlgorithmKeySize = 256,

        // A type that subclasses KeyedHashAlgorithm
        ValidationAlgorithmType = typeof(HMACSHA256)
    });

通常*类型属性必须指向具体,可实例化 (通过公共的无参数构造函数) 的实现SymmetricAlgorithmKeyedHashAlgorithm,但系统特殊的情况下等某些值typeof(Aes)为方便起见。Generally the *Type properties must point to concrete, instantiable (via a public parameterless ctor) implementations of SymmetricAlgorithm and KeyedHashAlgorithm, though the system special-cases some values like typeof(Aes) for convenience.

备注

SymmetricAlgorithm 必须 ≥ 128 位的密钥长度和 ≥ 64 位为单位的块大小,并且它必须支持使用 PKCS #7 填充 CBC 模式加密。The SymmetricAlgorithm must have a key length of ≥ 128 bits and a block size of ≥ 64 bits, and it must support CBC-mode encryption with PKCS #7 padding. KeyedHashAlgorithm 必须具有的摘要的大小 > = 128 位,并且它必须支持密钥长度等于哈希算法的摘要的长度。The KeyedHashAlgorithm must have a digest size of >= 128 bits, and it must support keys of length equal to the hash algorithm's digest length. KeyedHashAlgorithm 并非是严格要求,为 HMAC。The KeyedHashAlgorithm isn't strictly required to be HMAC.

指定自定义 Windows CNG 算法Specifying custom Windows CNG algorithms

若要指定自定义 Windows CNG 算法的 HMAC 验证使用 CBC 模式加密,创建CngCbcAuthenticatedEncryptorConfiguration实例,它包含的算法的信息:To specify a custom Windows CNG algorithm using CBC-mode encryption with HMAC validation, create a CngCbcAuthenticatedEncryptorConfiguration instance that contains the algorithmic information:

services.AddDataProtection()
    .UseCustomCryptographicAlgorithms(
        new CngCbcAuthenticatedEncryptorConfiguration()
    {
        // Passed to BCryptOpenAlgorithmProvider
        EncryptionAlgorithm = "AES",
        EncryptionAlgorithmProvider = null,

        // Specified in bits
        EncryptionAlgorithmKeySize = 256,

        // Passed to BCryptOpenAlgorithmProvider
        HashAlgorithm = "SHA256",
        HashAlgorithmProvider = null
    });

若要指定自定义 Windows CNG 算法的 HMAC 验证使用 CBC 模式加密,创建CngCbcAuthenticatedEncryptionSettings实例,它包含的算法的信息:To specify a custom Windows CNG algorithm using CBC-mode encryption with HMAC validation, create a CngCbcAuthenticatedEncryptionSettings instance that contains the algorithmic information:

services.AddDataProtection()
    .UseCustomCryptographicAlgorithms(
        new CngCbcAuthenticatedEncryptionSettings()
    {
        // Passed to BCryptOpenAlgorithmProvider
        EncryptionAlgorithm = "AES",
        EncryptionAlgorithmProvider = null,

        // Specified in bits
        EncryptionAlgorithmKeySize = 256,

        // Passed to BCryptOpenAlgorithmProvider
        HashAlgorithm = "SHA256",
        HashAlgorithmProvider = null
    });

备注

对称块加密算法的密钥长度必须 > = 128 位的块大小 > = 64 位,并且它必须支持使用 PKCS #7 填充 CBC 模式加密。The symmetric block cipher algorithm must have a key length of >= 128 bits, a block size of >= 64 bits, and it must support CBC-mode encryption with PKCS #7 padding. 哈希算法必须具有的摘要的大小 > = 128 位并且必须支持正在打开与 BCRYPT_ALG_处理_HMAC_标志的标志。The hash algorithm must have a digest size of >= 128 bits and must support being opened with the BCRYPT_ALG_HANDLE_HMAC_FLAG flag. *提供程序属性可以设置为 null 以使用指定的算法的默认提供程序。The *Provider properties can be set to null to use the default provider for the specified algorithm. 请参阅BCryptOpenAlgorithmProvider文档了解详细信息。See the BCryptOpenAlgorithmProvider documentation for more information.

若要指定自定义 Windows CNG 算法使用 Galois/计数器模式加密进行验证,创建CngGcmAuthenticatedEncryptorConfiguration实例,它包含的算法的信息:To specify a custom Windows CNG algorithm using Galois/Counter Mode encryption with validation, create a CngGcmAuthenticatedEncryptorConfiguration instance that contains the algorithmic information:

services.AddDataProtection()
    .UseCustomCryptographicAlgorithms(
        new CngGcmAuthenticatedEncryptorConfiguration()
    {
        // Passed to BCryptOpenAlgorithmProvider
        EncryptionAlgorithm = "AES",
        EncryptionAlgorithmProvider = null,

        // Specified in bits
        EncryptionAlgorithmKeySize = 256
    });

若要指定自定义 Windows CNG 算法使用 Galois/计数器模式加密进行验证,创建CngGcmAuthenticatedEncryptionSettings实例,它包含的算法的信息:To specify a custom Windows CNG algorithm using Galois/Counter Mode encryption with validation, create a CngGcmAuthenticatedEncryptionSettings instance that contains the algorithmic information:

services.AddDataProtection()
    .UseCustomCryptographicAlgorithms(
        new CngGcmAuthenticatedEncryptionSettings()
    {
        // Passed to BCryptOpenAlgorithmProvider
        EncryptionAlgorithm = "AES",
        EncryptionAlgorithmProvider = null,

        // Specified in bits
        EncryptionAlgorithmKeySize = 256
    });

备注

对称块加密算法的密钥长度必须 > = 128 位的块大小为完全 128 位,并且它必须支持 GCM 加密。The symmetric block cipher algorithm must have a key length of >= 128 bits, a block size of exactly 128 bits, and it must support GCM encryption. 可以设置EncryptionAlgorithmProvider属性设置为 null 以使用指定的算法的默认提供程序。You can set the EncryptionAlgorithmProvider property to null to use the default provider for the specified algorithm. 请参阅BCryptOpenAlgorithmProvider文档了解详细信息。See the BCryptOpenAlgorithmProvider documentation for more information.

指定其他自定义算法Specifying other custom algorithms

尽管不公开为第一类 API,数据保护系统是算法的可扩展,足以允许指定几乎任何类型。Though not exposed as a first-class API, the Data Protection system is extensible enough to allow specifying almost any kind of algorithm. 例如,就可以使包含硬件安全模块 (HSM) 中的所有密钥并提供加密和解密例程的核心的自定义实现。For example, it's possible to keep all keys contained within a Hardware Security Module (HSM) and to provide a custom implementation of the core encryption and decryption routines. 请参阅IAuthenticatedEncryptor核心加密扩展性有关详细信息。See IAuthenticatedEncryptor in Core cryptography extensibility for more information.

保存密钥托管在 Docker 容器中时Persisting keys when hosting in a Docker container

在中承载时Docker容器,应在维护密钥:When hosting in a Docker container, keys should be maintained in either:

  • 是一个 Docker 卷仍然存在超出容器的生存期,如共享的卷或主机装入的卷,一个文件夹。A folder that's a Docker volume that persists beyond the container's lifetime, such as a shared volume or a host-mounted volume.
  • 外部提供程序,如Azure 密钥保管库RedisAn external provider, such as Azure Key Vault or Redis.

其他资源Additional resources