ASP.NET Core 数据保护(Data Protection)中篇

前言

上篇主要是对 ASP.NET Core 的 Data Protection 做了一个简单的介绍,本篇主要是介绍一下API及使用方法。

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 TimeOffset,TimeSpan等参数来设置时间。

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

配置数据保护

在我们的 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, 下篇介绍一些高级的用法。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • ASP.NET Core配置教程之读取配置信息

    提到"配置"二字,我想绝大部分.NET开发人员脑海中会立马浮现出两个特殊文件的身影,那就是我们再熟悉不过的app.config和web.config,多年以来我们已经习惯了将结构化的配置信息定义在这两个文件之中.到了.NET Core的时候,很多我们习以为常的东西都发生了改变,其中也包括定义配置的方式.总的来说,新的配置系统显得更加轻量级,并且具有更好的扩展性,其最大的特点就是支持多样化的数据源.我们可以采用内存的变量作为配置的数据源,也可以直接配置定义在持久化的文件甚至数据库中. 由

  • 解决asp.net core在输出中文时乱码的问题

    前言 作为一个.NET Web开发者,我最伤心的时候就是项目开发部署时面对Windows Server上贫瘠的解决方案,同样是神器Nginx,Win上的Nginx便始终不如Linux上的,你或许会说"干嘛不用windows自带的NLB呢",那这就是我这个小鸟的从众心理了,君不见Stack Overflow 2016最新架构中,用的负载和缓存技术也都是采用在Linux上已经成熟的解决方案吗.没办法的时候找个适合的解决办法是好事,有办法的时候当然要选择最好的解决办法. 所幸,.ASP.NE

  • ASP.NET Core 1.0实现邮件发送功能

    准备将一些项目迁移到 asp.net core 先从封装类库入手,在遇到邮件发送类时发现在 asp.net core 1.0中并示提供SMTP相关类库,于是网上一搜发现了MailKit 好东西一定要试一下,何况是开源,下面是代码可实现SMTP邮件发送: using MailKit.Net.Smtp; using MailKit.Security; using MimeKit; using System.Threading.Tasks; namespace ConsoleApp1 { public

  • 云服务器下搭建ASP.NET Core环境

    最近.net core如火如荼,国内这方面环境搭建方面的文档也非常多,但是不少已经是过时的,就算按照那个流程走下去也避免不了一些地方早就不一样了.所以下面我将从头到尾的教大家搭建一次环境,并且成功运行官网的demo. 一.系统环境 本次笔者因为懒的去做虚拟机,所以注册了一个云提供商的试用账户作为本次的主机. 系统: Ubuntu Server 14.04.2 LTS 64bit Mono: 1.0.0-rc1-update1 Coreclr: 1.0.0-rc1-update1 二.正文 1.首

  • ASP.NET Core 数据保护(Data Protection)上篇

    前言  上一篇记录了如何在 Kestrel 中使用 HTTPS(SSL), 也是我们目前项目中实际使用到的. 数据安全往往是开发人员很容易忽略的一个部分,包括我自己.近两年业内也出现了很多因为安全问题导致了很多严重事情发生,所以安全对我们开发人员很重要,我们要对我们的代码的安全负责. 在工作中,我们常常会见到 encode,base64,sha256, rsa, hash,encryption, md5 等,一些人对他们还傻傻分不清楚,也不知道什么时候使用他们,还有一些人认为MD5就是加密算法.

  • ASP.NET Core MVC 配置全局路由前缀

    ASP.NET Core MVC 配置全局路由前缀 前言 大家好,今天给大家介绍一个 ASP.NET Core MVC 的一个新特性,给全局路由添加统一前缀.严格说其实不算是新特性,不过是Core MVC特有的. 应用背景 不知道大家在做 Web Api 应用程序的时候,有没有遇到过这种场景,就是所有的接口都是以 /api 开头的,也就是我们的api 接口请求地址是像这样的: http://www.example.com/api/order/333 或者是这样的需求 http://www.exa

  • Linux(Ubuntu)下搭建ASP.NET Core环境

    今天来学习一下ASP.NET Core 运行在Ubuntu中.无需安装mono . 环境 Ubuntu 14.04.4 LTS 服务器版 全新安装系统. 下载地址:http://mirrors.neusoft.edu.cn/ubuntu-releases/14.04.4/ubuntu-14.04.4-server-amd64.iso 你也可以下载桌面版安装. 下载地址:http://mirrors.neusoft.edu.cn/ubuntu-releases/14.04.4/ 安装DNVM 首先

  • win10下ASP.NET Core部署环境搭建步骤

    随着ASP.NET Core 1.0 rtm的发布,网上有许多相关.net core 相关文章,今刚好有时间也在win10环境上搭建下 ASP.NET Core的部署环境,把过程记录下给大家. 1. 开发运行环境 1> Visual Studio 2015 Update 3* 2> .NET Core 1.0 for Visual Studio (包括asp.net core 模板,其中如果机器上没有.net core sdk会默认安装)地址https://go.microsoft.com/f

  • ASP.NET Core集成微信登录

    工具: Visual Studio 2015 update 3 Asp.Net Core 1.0 1 准备工作 申请微信公众平台接口测试帐号,申请网址:(http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login).申请接口测试号无需公众帐号,可以直接体验和测试公众平台所有高级接口. 1.1 配置接口信息 1.2 修改网页授权信息 点击"修改"后在弹出页面填入你的网站域名: 2 新建网站项目 2.1 选择ASP.NET C

  • asp.net core实现文件上传功能

    本文实例为大家分享了单文件上传.多文件上传的功能,供大家参考,具体内容如下 单文件上传  上传文件在Web应用程序中是一个常见的功能.在asp.net core中上传文件并保存在服务器上,是很容易的.下面就来演示一下怎么样在 ASP.NET Core项目中进行文件上传.  首先,创建一个 asp.net core 项目,然后在Controller文件件添加一个HomeController,然后在 Views 文件夹的 Home 文件夹里添加一个 New.cshtml 视图文件.如下图: 添加一个

随机推荐