

ASP.NET Core 6框架揭秘实例演示[20]:“数据保护”框架基于文件的密钥存储
source link: https://www.cnblogs.com/artech/p/inside-asp-net-core-6-20.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

《数据加解密与哈希》演示了“数据保护”框架如何用来对数据进行加解密,而“数据保护”框架的核心是“密钥管理”。数据保护框架以XML的形式来存储密钥,默认的IKeyManager实现类型为XmlKeyManager。接下来我们通过模拟代码和实例演示的形式来介绍一下XmlKeyManager对象针对密钥的创建、撤销和回收的实现原理。(本篇提供的实例已经汇总到《ASP.NET Core 6框架揭秘-实例演示版》)
[S1308]基于本地文件系统的密钥管理(密钥创建)(源代码)
[S1309]基于本地文件系统的密钥管理(密钥撤销)(源代码)
[S1308]基于本地文件系统的密钥管理(密钥创建)
接下来我们通过如下这个简单的演示实例来看看创建出来的密钥对应的XML具有怎样的结构。如代码片段所示,我们通过依赖注入容器得到IKeyManager对象,并用它创建了三个密钥。在调用AddDataProtection扩展方法后,我们调用返回IDataProtectionBuilder对象的PersistKeysToFileSystem扩展方法,其目的是利用FileSystemXmlRepository对象将代表创建密钥和密钥撤销操作的XML存储在指定的目录(“c:\keys”)下。
using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection.KeyManagement; using Microsoft.Extensions.DependencyInjection; var directory = "c:\\keys"; var services = new ServiceCollection(); services .AddDataProtection() .PersistKeysToFileSystem(new DirectoryInfo(directory)); var keyManager = services .BuildServiceProvider() .GetRequiredService<IKeyManager>(); var key1 = keyManager.CreateNewKey(DateTimeOffset.Now, DateTimeOffset.Now.AddDays(1)); var key2 = keyManager.CreateNewKey(DateTimeOffset.Now ,DateTimeOffset.Now.AddDays(2)); var key3 = keyManager.CreateNewKey(DateTimeOffset.Now, DateTimeOffset.Now.AddDays(3)); Console.WriteLine(key1.KeyId); Console.WriteLine(key2.KeyId); Console.WriteLine(key3.KeyId);
演示程序运行后会将创建的三个密钥的ID以如图1的形式输出到控制台上。与此同时,目录“c:\keys\”下会出现三个对应的XML文件。从图中可以看出,表示密钥文件的名称正是调用IXmlRepository对象的StoreElement方法时指定的名称。
图1 以XML文件存储的密钥
如下所示的是其中一个密钥对应的XML文件的内容。通过IAuthenticatedEncryptorDescriptor对象导出的XML体现在<key>/<descriptor>节点上。可以看出当前环境下默认采用的加密和哈希算法分别是AES_256_CBC和HMACSHA256,AuthenticatedEncryptorDescriptorDeserializer为采用的反序列化器类型。
<?xml version="1.0" encoding="utf-8"?> <key id="3f8769f0-78c8-42f2-9f13-102d83bb298c" version="1"> <creationDate>2022-03-12T09:47:38.4677311Z</creationDate> <activationDate>2022-03-12T17:47:38.4630578+08:00</activationDate> <expirationDate>2022-03-13T17:47:38.4674829+08:00</expirationDate> <descriptor deserializerType="Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"> <descriptor> <encryption algorithm="AES_256_CBC" /> <validation algorithm="HMACSHA256" /> <masterKey p4:requiresEncryption="true" xmlns:p4="http://schemas.asp.net/2015/03/dataProtection"> <!-- Warning: the key below is in an unencrypted form. --> <value>oFjUpRP4cKwp0QQctjibDN8QK3m76uQAlkGZ1V4E5sb9l9Yn4zzgjHyxpoJ7qENqBGwdD0A11U90YzGRb53p+g==</value> </masterKey> </descriptor> </descriptor> </key>
[S1309]基于本地文件系统的密钥管理(密钥撤销)
我们接着来看看密钥的撤销。如果是针对单个密钥的撤销,该密钥的ID会通过名为“key”的子元素保存下来。如果需要撤销现有的所有密钥,这个key元素的值会设置为“*”。两者采用的文件名称也不相同,格式分别为“revocation-{KeyId}”和“revocation-{RevocationDate}”。我们接下来演示针对密钥的撤销。如下面的代码片段所示,在得到IKeyManager对象之后,我们调用其GetAllKeys方法得到所有密钥。在调用RevokeKey方法撤销第一个得到密钥之后,我们调用RevokeAllKeys方法将现有密钥全部撤销掉。
using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection.KeyManagement; using Microsoft.Extensions.DependencyInjection; var directory = "c:\\keys"; var services = new ServiceCollection(); services .AddDataProtection() .PersistKeysToFileSystem(new DirectoryInfo(directory)); var keyManager = services .BuildServiceProvider() .GetRequiredService<IKeyManager>(); var key = keyManager.GetAllKeys().First(); keyManager.RevokeKey(key.KeyId); keyManager.RevokeAllKeys(DateTimeOffset.Now, "Revocation Test");
演示程序执行后会在密钥存储目录(c:\keys\)下生成两个名称前缀为“revocation-”的XML文件。与上面的代码进行比较,我们会发现XML文件的名称依然是调用IXmlRepository对象的StoreElement方法指定的名称。
图2 描述密钥撤销的XML文件
如下所示的是这两个描述密钥撤销的XML文件的内容,可以看出XML结构与前面提供的RevokeKey和RevokeAllKeys方法的定义是匹配的。
revocation-184d9274-78f1-4352-bbed-1d0d6803ddad.xml
<?xml version="1.0" encoding="utf-8"?> <revocation version="1"> <revocationDate>2022-03-12T09:54:48.1157691Z</revocationDate> <key id="184d9274-78f1-4352-bbed-1d0d6803ddad" /> <reason /> </revocation>
revocation-20220312T0954481194781Z.xml
<?xml version="1.0" encoding="utf-8"?> <revocation version="1"> <revocationDate>2022-03-12T17:54:48.1194781+08:00</revocationDate> <!-- All keys created before the revocation date are revoked. --> <key id="*" /> <reason>Revocation Test</reason> </revocation>
Recommend
-
6
ASP.NET Core 6框架揭秘实例演示[01]: 编程初体验 作为《ASP.NET C...
-
9
ASP.NET Core 6框架揭秘实例演示[06]:依赖注入框架设计细节 由于依...
-
8
作为《ASP.NET Core 3框架揭秘》的升级版,《ASP.NET Core 6框架揭秘》提供了很多新的章节,同时对现有的内容进行大量的修改。虽然本书旨在对ASP.NET Core框架的架构设计和实现原理进行剖析,但是其中提供的
-
6
ASP.NET Core框架建立在一个依赖注入框架之上,已注入的方式消费服务已经成为了ASP.NET Core基本的编程模式。为了使读者能够更好地理解原生的注入框架框架,我按照类似的设计创建了一个简易版本的依赖注入框架,并它命名为“Cat”。本篇提供的四个实例主要体现了...
-
7
ASP.NET Core 6框架揭秘实例演示[12]:诊断跟踪的进阶用法 一个好...
-
6
毫不夸张地说,整个ASP.NET Core就是建立在依赖注入框架之上的。ASP.NET Core应用在启动时构建管道所需的服务,以及管道处理请求使用到的服务,均来源于依赖注入容器。依赖注入容器不仅为ASP.NET Core框架自身提供必要的服务,还为应用程序提供服务,依赖注入已...
-
4
我们倾向于将IConfiguration对象转换成一个具体的对象,以面向对象的方式来使用配置,我们将这个转换过程称为配置绑定。除了将配置树叶子节点配置节的绑定为某种标量对象外,我们还可以直接将一个配置节绑定为一个具有对应结构的符合对象。除此之外,配置绑定还...
-
11
ASP.NET Core可以视为一种底层框架,它为我们构建出了基于管道的请求处理模型,这个管道由一个服务器和多个中间件构成,而与路由相关的EndpointRoutingMiddleware和EndpointMiddleware是两个最为重要的中间件。MVC和gRPC开发框架就建立在路由基础上。本篇提供了...
-
6
ASP.NET Core应用具有很多读取文件的场景,如读取配置文件、静态Web资源文件(如CSS、JavaScript和图片文件等)、MVC应用的视图文件,以及直接编译到程序集中的内嵌资源文件。这些文件的读取都需要使用一个IFileProvider对象。IFileProvider对象构建了一个抽象...
-
3
ASP.NET应用并没有对如何定义授权策略做硬性规定,所以我们完全根据用户具有的任意特性(如性别、年龄、学历、所在地区、宗教信仰、政治面貌等)来判断其是否具有获取目标资源或者执行目标操作的权限,但是针对角色的授权策略依然是最常用的。角色(或者用户组)实际...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK