2019独角兽企业重金招聘Python工程师标准>>>

API 接口

ASP.NET Core Data Protectio 主要对普通开发人员提供了两个接口,IDataProtectionProvider 和 IDataProtector
我们先看一下这两个接口的关系:

namespace Microsoft.AspNetCore.DataProtection
{//// 摘要://     An interface that can provide data protection services.public interface IDataProtector : IDataProtectionProvider{byte[] Protect(byte[] plaintext);byte[] Unprotect(byte[] protectedData);}
}

可以看到,IDataProtector继承自IDataProtectionProvider ,并且提供了两个方法 Protect 和 Unprotect ,从命名来看,一个是加密,一个是解密。而他们的签名都是传入一个byte数组,这也就意味着他们可以加密和解密一切对象。返回的也是byte数组,也就是说在实际的使用过程中,我们应该自己添加或者使用系统的一些扩展方法来具体化我们的需求。

我们再看一下IDataProtectionProvider接口:

namespace Microsoft.AspNetCore.DataProtection
{public interface IDataProtectionProvider{IDataProtector CreateProtector(string purpose);}
}

IDataProtectionProvider提供了一个方法,通过传入一个 purpose字符串(见后面详细介绍)来生成一个IDataProtector接口对象。
从这个接口的命名来看,它以Provider结尾,也就是说这部分我们可以实现自己的一套加解密的东西。

我们在阅读微软项目的源代码的时候,经常看一些以xxxxProvider结尾的对象,那么它的职责是什么,同时扮演什么样的角色呢?
其实这是微软专门为ASP.NET设计的一个设计模式,叫Provider Model设计模式,也可以说它是由微软发明的,它不属于23种设计模式中的一种,从功能上来看的话,应该是工厂和策略的结合体。自ASP.NET 2.0开始,微软就开始引入这种设计模式,最开始主要是用于实现应用程序的配置的多个实现。比如开发者最熟悉的web.config中, 针对于数据库连接字符串的配置, 还有二进制,再比如XML啊等等很多,现在其他地方这种模式也用的越来越多起来。

再来说一下CreateProtector方法签名中的 purpose 这个字符串,在上一篇博文中为了读者好理解,我把传入的purpose说成可以理解为一个公钥,其实这个说法是不严谨的,可以理解为一个标识,指示当前Protector的用途。

在使用IDataProtector的时候,会发现它还有一些扩展方法位于Microsoft.AspNetCore.DataProtection命名空间下:

public static class DataProtectionCommonExtensions
{public static IDataProtector CreateProtector(this IDataProtectionProvider provider, IEnumerable<string> purposes);public static IDataProtector CreateProtector(this IDataProtectionProvider provider, string purpose, params string[] subPurposes);public static IDataProtector GetDataProtector(this IServiceProvider services, IEnumerable<string> purposes);public static IDataProtector GetDataProtector(this IServiceProvider services, string purpose, params string[] subPurposes);public static string Protect(this IDataProtector protector, string plaintext);public static string Unprotect(this IDataProtector protector, string protectedData);
}

可以看到,CreateProtector还提供了可以传多个purpose的方法(IEnumerable,params string[]),为什么会有这种需求呢?

其实DataProtector是有层次结构的,再看一下IDataProtector接口,它自身也实现了IDataProtectionProvider接口,就是说IDataProtector自身也可以再创建IDataProtector

举个例子:我们在做一个消息通讯的系统,在消息通讯的过程中,需要对用户的会话进行加密,我们使用CreateProtector("Security.BearerToken")加密。但是加密的时候并不能保证消息是不受信任的客户端发过来的,所以想到了CreateProtector("username")来进行加密,这个时候假如有一个用户的用户名叫“Security.BearerToken”,那么就和另外一个使用Security.BearerToken作为标示的 Protector 冲突了,所以我们可以使用
CreateProtector([ “Security.BearerToken”, “User: username” ])这种方式。它相当于
provider.CreateProtector(“Security.BearerToken).CreateProtector(“User: username”)。 意思就是先创建一个Protector叫“Security.BearerToken”,然后再在purpose1下创建一个名为“User: username”的Protector。

用户密码哈希

Microsoft.AspNetCore.Cryptography.KeyDerivation命名空间下提供了一个KeyDerivation.Pbkdf2方法用来对用户密码进行哈希。

具有生命周期限制的加密

有些时候,我们需要一些具有过期或者到期时间的加密字符串,比如一个用户在找回密码的时候,我们向用户的邮箱发送一封带有重置命令的一封邮件,这个重置命令就需要有一个过期时间了,超过这个过期时间后就失效,在以前我们可能需要向数据库存储一个时间来标记发送时间,然后再解密对比和数据库的时间差来验证。

现在我们不需要这么做了,ASP.NET Core 默认提供了一个接口叫 ITimeLimitedDataProtector ,我们先看一下这个接口的定义:

CreateProtector(string purpose) : ITimeLimitedDataProtector This API is similar to the existing IDataProtectionProvider.CreateProtector in that it can be used to create purpose chains from a root time-limited protector.
Protect(byte[] plaintext, DateTimeOffset expiration) : byte[]
Protect(byte[] plaintext, TimeSpan lifetime) : byte[]
Protect(byte[] plaintext) : byte[]
Protect(string plaintext, DateTimeOffset expiration) : string
Protect(string plaintext, TimeSpan lifetime) : string
Protect(string plaintext) : string

ITimeLimitedDataProtector提供了数个重载方法用来设定带有生命周期的加密方法,用户可以通过Date TimeOffsetTimeSpan等参数来设置时间。

有对应的加密,就有相对应的解密方法,在这里就不详细介绍了。有兴趣的同学可以去看一下官方文档。

配置数据保护

在我们的 ASP.NET Core 运行的时候,系统会基于当前机器的运行环境默认配置一些关于 Data Protection 的东西,但是有些时候可能需要对这些配置做一些改变,比如在分布式部署的时候,在上一篇博文的末尾也提到过,下面就来看一下具体怎么配置的吧。

上篇文章已经提到过,我们通过以下方式来把 Data Protection 注册到服务中:

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

其中AddDataProtection 返回的是一个 IDataProtectionBuilder 接口,这个接口提供了一个扩展方法PersistKeysToFileSystem() 来存储私钥。可以通过它传入一个路径来指定私钥存储的位置:

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

可以传入一个共享文件夹,来存储私钥,这样在不同机器的私钥就可以保存到一个位置了。可以通过此种方式在分布式部署的时候,隔离开了机器的差异化。
如果你觉得不安全,还可以配置一个X.509证书来,进行加密:

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

上篇文章讲过,Data Protection 的默认保存时间是90天,你可以通过以下方式来修改默认的保存时间:

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

默认情况下,即使使用相同的物理密钥库,Data Protection 也会把不同的应用程序隔离开,因为这样可以防止从一个应用程序获取另外一个应用程序的密钥。所以如果是相同的应用程序,可以设置相同的应用程序名称:

public void ConfigureServices(IServiceCollection services)
{services.AddDataProtection().SetApplicationName("my application");
}

有时候需要禁用应用程序生成密钥,或者是说我只有一个程序用来生成或者管理密钥,其他程序只是负责读的话,那么可以这样:

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

修改加密算法

可以使用UseCryptographicAlgorithms方法来修改ASP.NET Core Data Protection的默认加密算法,如下:

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

总结

本篇主要是介绍了一些常用的API, 下篇介绍一些高级的用法。

转载于:https://my.oschina.net/dingliu/blog/759899

ASP.NET Core 数据保护(Data Protection)【中】相关推荐

  1. [第二篇]如何在ASP.Net Core的生产环境中使用OAuth保护swagger ui

    在我上篇文章如何在ASP.Net Core的生产环境中保护swagger ui中,我们讨论了如何使用基本身份验证来保护 swagger ui. 使用 OAuth 2.0 和 OpenIdConnect ...

  2. ASP.NET Core依赖注入容器中的动态服务注册

    介绍 在ASP.NET Core中,每当我们将服务作为依赖项注入时,都必须将此服务注册到ASP.NET Core依赖项注入容器.但是,一个接一个地注册服务不仅繁琐且耗时,而且容易出错.因此,在这里,我 ...

  3. Asp.Net Core 中间件应用实战中你不知道的那些事

    一.概述 这篇文章主要分享Endpoint 终结点路由的中间件的应用场景及实践案例,不讲述其工作原理,如果需要了解工作原理的同学, 可以点击查看以下两篇解读文章: •Asp.Net Core EndP ...

  4. 在ASP.NET Core 3.1 MVC中集成Vue.js V4和使用Dropzone文件上传

    目录 介绍 先决条件 Node.js的介绍 您已经安装了Node.js/NPM吗? Node/ NPM版本相关的常见错误 Vue.js简介 安装Vue.js V4 NET Core介绍 安装Visua ...

  5. VS 2017开发ASP.NET Core Web应用过程中发现的一个重大Bug

    今天试着用VS 2017去开发一个.net core项目,想着看看.net core的开发和MVC5开发有什么区别,然后从中发现了一个VS2017的Bug. 首先,我们新建项目,ASP.NET Cor ...

  6. NET问答: 如何在 ASP.NET Core 的 .json 文件中读取 AppSettings ?

    咨询区 Oluwafemi: 在 appsettings.json 中我有如下的 AppSettings 实体数据,如下代码所示: {"AppSettings": {"t ...

  7. 【Docker】Asp.net core在docker容器中的端口问题

    还记得[One by one系列]一步步学习docker(三)--实战部署dotnetcore中遇到的问题么?容器内部启动始终是80端口,并不由命令左右. docker run --name cont ...

  8. TechEmpower Web 框架性能第19轮测试结果正式发布,ASP.NET Core在主流框架中拔得头筹...

    TechEmpower第19轮编程语言框架性能排行榜2020年5月28日正式发布,详见官方博客:https://www.techempower.com/blog/2020/05/28/framewor ...

  9. ASP.NET Core Web API 集成测试中使用 Bearer Token

    在 ASP.NET Core Web API 集成测试一文中, 我介绍了ASP.NET Core Web API的集成测试. 在那里我使用了测试专用的Startup类, 里面的配置和开发时有一些区别, ...

最新文章

  1. Mysql迁移到Oracle方法
  2. 《开源思索集》一Source Code + X
  3. 计算机检索技术与技巧的检索式为,第四章计算机检索技术和数据库检索方式.ppt...
  4. 面向视频的全新AI架构 —— 阿里云智能视觉技术全解
  5. FunDA(7)- Reactive Streams to fs2 Pull Streams
  6. this(C# 参考)
  7. symbian VC环境配置及其helloword详解
  8. 新版谷歌地图的好处和优点
  9. 外贸常用术语_外贸常用术语总结.doc
  10. Navicat简单使用方法。
  11. 遥感监测草原产草量的方法
  12. 【Docker】fuse: device not found, try ‘modprobe fuse‘ first
  13. 小巧的绿色html导航引导页
  14. 原来RA是Router Advertisement的意思
  15. 网络爬虫获取股票历史行情
  16. 中国企业服务市场为啥“小老头”居多?
  17. 场景化组件开源,融云持续回馈开源生态
  18. 点击电脑图标,显示电脑界面。点击相同的二维码图标,显示二维码界面(七)
  19. 阿里巴巴盒马前端面试总结
  20. unix高级编程-fork之后父子进程共享文件

热门文章

  1. 大数据分布式集群搭建(9)
  2. 在Windows上使用LaTeX
  3. php获取等于符号后面的参数,php获取URL中带#号等特殊符号参数的解决方法
  4. 实战:RocketMQ削峰,这一篇就够了
  5. IOS后台运行机制详解(一)
  6. python进程线程处理模块_python程序中的线程操作 concurrent模块使用详解
  7. 如何在10分钟内进行可用性测试
  8. c语言ctype中替换查找字符,c – std :: ctype是否总是按“C”语言环境对字符进行分类?...
  9. RAID 与 LVM 磁盘阵列技术
  10. html6个圆圈放一排,html中两个选择框如何并排放置(一)