- 在 ASP.NET Core中的核心加密可扩展性Core cryptography extensibility in ASP.NET Core
- IAuthenticatedEncryptorIAuthenticatedEncryptor
- 如何创建 IAuthenticatedEncryptorHow to create an IAuthenticatedEncryptor
- IAuthenticatedEncryptorDescriptor (ASP.NET Core 2.x 仅)IAuthenticatedEncryptorDescriptor (ASP.NET Core 2.x only)
- XML 序列化XML Serialization
- IAuthenticatedEncryptorDescriptorDeserializerIAuthenticatedEncryptorDescriptorDeserializer
- 顶级工厂The top-level factory
在 ASP.NET Core中的核心加密可扩展性Core cryptography extensibility in ASP.NET Core
本文内容
警告
实现以下接口的任何类型应该是线程安全的多个调用方。
IAuthenticatedEncryptorIAuthenticatedEncryptor
IAuthenticatedEncryptor接口是加密子系统的基本构建基块。通常,每个密钥有一个 IAuthenticatedEncryptor,IAuthenticatedEncryptor 实例包装执行加密操作所需的所有加密密钥材料和算法信息。
顾名思义,类型负责提供经过身份验证的加密和解密服务。它公开了以下两个 Api。
Decrypt(ArraySegment<byte> ciphertext, ArraySegment<byte> additionalAuthenticatedData) : byte[]
Encrypt(ArraySegment<byte> plaintext, ArraySegment<byte> additionalAuthenticatedData) : byte[]
加密方法返回包含到加密纯文本和身份验证标记的 blob。身份验证标记必须包含其他经过身份验证的数据(AAD),尽管 AAD 本身无需从最终有效负载中恢复。解密方法验证身份验证标记并返回已解码的有效负载。所有失败(除了 System.argumentnullexception 和类似)都应该 homogenized 为 System.security.cryptography.cryptographicexception。
备注
IAuthenticatedEncryptor 实例本身实际上不需要包含密钥材料。例如,实现可能会委托给所有操作的 HSM。
如何创建 IAuthenticatedEncryptorHow to create an IAuthenticatedEncryptor
IAuthenticatedEncryptorFactory接口表示知道如何创建IAuthenticatedEncryptor实例的类型。其 API 如下所示。
- CreateEncryptorInstance (IKey 键): IAuthenticatedEncryptor
对于任何给定的 IKey 实例,由其 CreateEncryptorInstance 方法创建的任何经过身份验证的加密程序都应视为等效,如以下代码示例所示。
// we have an IAuthenticatedEncryptorFactory instance and an IKey instance
IAuthenticatedEncryptorFactory factory = ...;
IKey key = ...;
// get an encryptor instance and perform an authenticated encryption operation
ArraySegment<byte> plaintext = new ArraySegment<byte>(Encoding.UTF8.GetBytes("plaintext"));
ArraySegment<byte> aad = new ArraySegment<byte>(Encoding.UTF8.GetBytes("AAD"));
var encryptor1 = factory.CreateEncryptorInstance(key);
byte[] ciphertext = encryptor1.Encrypt(plaintext, aad);
// get another encryptor instance and perform an authenticated decryption operation
var encryptor2 = factory.CreateEncryptorInstance(key);
byte[] roundTripped = encryptor2.Decrypt(new ArraySegment<byte>(ciphertext), aad);
// the 'roundTripped' and 'plaintext' buffers should be equivalent
IAuthenticatedEncryptorDescriptor接口表示知道如何创建IAuthenticatedEncryptor实例的类型。其 API 如下所示。
CreateEncryptorInstance() : IAuthenticatedEncryptor
ExportToXml() : XmlSerializedDescriptorInfo
与 IAuthenticatedEncryptor 一样,假定 IAuthenticatedEncryptorDescriptor 的实例包装一个特定键。这意味着,对于任何给定的 IAuthenticatedEncryptorDescriptor 实例,由其 CreateEncryptorInstance 方法创建的任何经过身份验证的加密程序都应视为等效,如以下代码示例中所示。
// we have an IAuthenticatedEncryptorDescriptor instance
IAuthenticatedEncryptorDescriptor descriptor = ...;
// get an encryptor instance and perform an authenticated encryption operation
ArraySegment<byte> plaintext = new ArraySegment<byte>(Encoding.UTF8.GetBytes("plaintext"));
ArraySegment<byte> aad = new ArraySegment<byte>(Encoding.UTF8.GetBytes("AAD"));
var encryptor1 = descriptor.CreateEncryptorInstance();
byte[] ciphertext = encryptor1.Encrypt(plaintext, aad);
// get another encryptor instance and perform an authenticated decryption operation
var encryptor2 = descriptor.CreateEncryptorInstance();
byte[] roundTripped = encryptor2.Decrypt(new ArraySegment<byte>(ciphertext), aad);
// the 'roundTripped' and 'plaintext' buffers should be equivalent
IAuthenticatedEncryptorDescriptor (ASP.NET Core 2.x 仅)IAuthenticatedEncryptorDescriptor (ASP.NET Core 2.x only)
IAuthenticatedEncryptorDescriptor接口表示一种类型,该类型知道如何将自身导出到 XML。其 API 如下所示。
- ExportToXml() : XmlSerializedDescriptorInfo
XML 序列化XML Serialization
IAuthenticatedEncryptor 和 IAuthenticatedEncryptorDescriptor 之间的主要区别在于,描述符知道如何创建加密程序并为其提供有效的参数。假设其实现依赖于 System.security.cryptography.symmetricalgorithm 和 KeyedHashAlgorithm 的 IAuthenticatedEncryptor。加密程序的工作就是使用这些类型,但不一定知道这些类型来自何处,因此,如果应用程序重启,则无法真正地写出如何重新创建其自身的正确说明。描述符在此基础上充当更高的级别。由于描述符知道如何创建加密程序实例(例如,它知道如何创建所需的算法),因此它可以将 XML 格式的知识序列化,以便可以在应用程序重置后重新创建加密程序实例。
描述符可以通过其 ExportToXml 例程进行序列化。此例程返回一个 XmlSerializedDescriptorInfo,其中包含两个属性:描述符的 System.xml.linq.xelement> 表示形式和表示IAuthenticatedEncryptorDescriptorDeserializer的类型,该类型可用于在给定相应 system.xml.linq.xelement> 的情况下恢复此描述符。
序列化描述符可能包含敏感信息,如加密密钥材料。数据保护系统在将信息保存到存储之前,对其进行内置支持。若要利用这一点,描述符应标记包含具有属性名称 "requiresEncryption" (xmlns "http://schemas.asp.net/2015/03/dataProtection")、值为 "true" 的敏感信息的元素。
提示
有一个用于设置此属性的帮助器 API。调用 System.xml.linq.xelement> MarkAsRequiresEncryption (),该扩展方法位于命名空间 AspNetCore。
也可能存在序列化描述符不包含敏感信息的情况。再次考虑存储在 HSM 中的加密密钥的情况。此描述符在序列化时无法写出密钥材料,因为 HSM 不会以纯文本形式公开材料。相反,描述符可能会写出密钥的密钥包装版本(如果 HSM 允许以这种方式导出)或 HSM 自己的密钥唯一标识符。
IAuthenticatedEncryptorDescriptorDeserializerIAuthenticatedEncryptorDescriptorDeserializer
IAuthenticatedEncryptorDescriptorDeserializer接口表示知道如何从 system.xml.linq.xelement> 反序列化 IAuthenticatedEncryptorDescriptor 实例的类型。它公开了单一方法:
- ImportFromXml (System.xml.linq.xelement> 元素): IAuthenticatedEncryptorDescriptor
ImportFromXml 方法采用IAuthenticatedEncryptorDescriptor返回的 system.xml.linq.xelement>,并创建原始 IAuthenticatedEncryptorDescriptor 的等效项。
实现 IAuthenticatedEncryptorDescriptorDeserializer 的类型应具有以下两个公共构造函数之一:
.ctor(IServiceProvider)
.ctor()
备注
传递给构造函数的 IServiceProvider 可能为 null。
顶级工厂The top-level factory
AlgorithmConfiguration类表示一种知道如何创建IAuthenticatedEncryptorDescriptor实例的类型。它公开一个 API。
- CreateNewDescriptor() : IAuthenticatedEncryptorDescriptor
将 AlgorithmConfiguration 看作顶级工厂。配置用作模板。它包装算法信息(例如,此配置使用 AES-128-GCM 主密钥生成描述符),但尚未与特定密钥相关联。
调用 CreateNewDescriptor 时,将仅为此调用创建新的密钥材料,并生成新的 IAuthenticatedEncryptorDescriptor 来包装此密钥材料以及使用该材料所需的算法信息。密钥材料可以在软件中创建(并保存在内存中),可以在 HSM 中创建和保存它。关键是,对 CreateNewDescriptor 的任何两次调用都不应创建等效的 IAuthenticatedEncryptorDescriptor 实例。
AlgorithmConfiguration 类型用作密钥创建例程(如自动密钥滚动)的入口点。若要更改所有将来键的实现,请在 KeyManagementOptions 中设置 AuthenticatedEncryptorConfiguration 属性。
IAuthenticatedEncryptorConfiguration接口表示知道如何创建IAuthenticatedEncryptorDescriptor实例的类型。它公开一个 API。
- CreateNewDescriptor() : IAuthenticatedEncryptorDescriptor
将 IAuthenticatedEncryptorConfiguration 看作顶级工厂。配置用作模板。它包装算法信息(例如,此配置使用 AES-128-GCM 主密钥生成描述符),但尚未与特定密钥相关联。
调用 CreateNewDescriptor 时,将仅为此调用创建新的密钥材料,并生成新的 IAuthenticatedEncryptorDescriptor 来包装此密钥材料以及使用该材料所需的算法信息。密钥材料可以在软件中创建(并保存在内存中),可以在 HSM 中创建和保存它。关键是,对 CreateNewDescriptor 的任何两次调用都不应创建等效的 IAuthenticatedEncryptorDescriptor 实例。
IAuthenticatedEncryptorConfiguration 类型用作密钥创建例程(如自动密钥滚动)的入口点。若要更改所有将来键的实现,请在服务容器中注册单一实例 IAuthenticatedEncryptorConfiguration。