对于web,安全是一个永久的话题,所以ASP.NET Core数据保护提供了一个简单,易用的加密API,可以用来保护数据,密钥管理和轮换。

ASP.NET Core的数据保护是根据本机的一个key来生成加密码,然后再用这个key来解密,如果key不一样,解密失败。默认情况下这个key的有效期是90天,当然这个值是可以被改变的。

默认数据保护key存放的位置,C:\Users\用户\AppData\Local\ASP.NET\DataProtection-Keys,如:key-a2b3132b-444b-4cfa-8530-922b7e991cd9.xml,是一个xml文件,里面记录了这个key的一些信息,创建时间,激活时间,过期时间,和加解密数据所用的命名空间,加密方式等信息,如下:

<?xml version="1.0" encoding="utf-8"?>
<key id="a2b3132b-444b-4cfa-8530-922b7e991cd9" version="1"><creationDate>2022-02-10T13:41:14.7492868Z</creationDate><activationDate>2022-02-10T13:41:14.7421157Z</activationDate><expirationDate>2022-05-11T13:41:14.7421157Z</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" /><encryptedSecret decryptorType="Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiXmlDecryptor, Microsoft.AspNetCore.DataProtection, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60" xmlns="http://schemas.asp.net/2015/03/dataProtection"><encryptedKey xmlns=""><!-- This key is encrypted with Windows DPAPI. --><value>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAAZeuIp6hZUGsfTgUuNoSSAAAAAACAAAAAAAQZgAAAAEAACAAAACpVhXOBzCWDrZmD13HwR6U3qHk7O2Pki1vPEBrtOJlrQAAAAAOgAAAAAIAACAAAAAPc2zwN10L4IVtN7tFsdQV0Cx7giHlNrWI6heArHHFt1ABAAACCCC8BhZwQ32ZZ67nBEi/tZS+HagViuS/xYtlUJOfzkJOmWg28KkBR2vM6Jo1Y1OY/AbIx6EhbGvZUkdL9aeGBy6A0GBS/3VC4/X8KV3sihRPhb1n924slVds0Y9p7J3p6sCLbhvh0ohhBe1pAENr1XkUnd2Ve4JQ0gVVgQ7vFJOonGGXGQ52dzmITzkJLYIqwNtksA31OmJUlJG7KJnrDEofKjQynvj9gXnOVnMpfHNk6v8v96WDlK7n9Ax3o/W238E7FtOVBKTNoIFWwyc40MR25IrkQdtMZ7HrODY1VRL9nuuexbVXq+5mt5QOyVgvZ1RK0sCwaBB3FSHwKmjskk+WpHXZpi3hjLx82F1gCpatSma01zDEDte0LZHRG9pVYgUXRwUaXX3G0uPuI2mXNpN57qIGZhCJC37cACIzJQ5NxuS+n9Rs6SjVykn78LBAAAAAkxOreUFzysrk5EeldARfOulsq/9OT2w/AFU9sRvPWgZPOieKcdAfIuNF09FgcyquX6IcNuydPn46Uy+saHia0w==</value></encryptedKey></encryptedSecret></descriptor></descriptor>
</key>

使用数据保护的代码也很简单,注入DataProtection服务就可以,只需要使用服务时,通过IDataProtectionProvider创建一个数据保护对象,在创建时可以添加目标字符串参数,来防隔离不同的目标字符串加密的数据,所以key和这个目标字符串都能起到隔离作用。

using Microsoft.AspNetCore.DataProtection;var builder = WebApplication.CreateBuilder(args);
//通过SetDefaultKeyLifetime更改默认值90天
builder.Services.AddDataProtection().SetDefaultKeyLifetime(TimeSpan.FromDays(10));
var app = builder.Build();app.MapGet("/encrypt/{str}", (IDataProtectionProvider provider, ILogger<Program> logger, string str) =>
{var protector = provider.CreateProtector("a.b.c");var sec = protector.Protect(str);logger.LogInformation(sec);return "加密:" + sec;
});
app.MapGet("/decrypt/{sec}", (IDataProtectionProvider provider, ILogger<Program> logger, string sec) =>
{var protector = provider.CreateProtector("a.b.c");var str = protector.Unprotect(sec);logger.LogInformation(str);return "解密:" + str;
});app.Run();

上面代码只是实现了单机部署,如果集群部署,比如k8s中的不同pod,生成的key分别保存在自己的pod里,那么外部访问又是随机分配的,这时就会频繁出现解密失败的情况,这就要集中管理key了,用redis或数据库都可以,这里用到的是SqlServer,首先创建存key的表,如下:

CREATE TABLE [dbo].[DataProtectionKeys1]([ID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY ,[FriendlyName] [varchar](64) NULL,[Xml] [text] NULL)

当有key保存进来时的结果如下:

其中字段key存的值如下,与本地文件存储的是一样的。

<key id="a32def14-9156-4c5e-946c-d3aa5b1a1743" version="1"> <creationDate>2022-02-10T14:20:37.5680295Z</creationDate>  <activationDate>2022-02-10T14:20:36.5853181Z</activationDate>  <expirationDate>2022-05-11T14:20:36.5853181Z</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 xmlns:p4="http://schemas.asp.net/2015/03/dataProtection" p4:requiresEncryption="true">  <!-- Warning: the key below is in an unencrypted form. -->  <value>gO70+leJQM8NJopS5VmMy+qkz0j+I9diBoCnxkqGxpqdXmyTULgAhMyu+3S4SJ0vjsx8Hxc+d/ipUgDBnkuQNw==</value> </masterKey> </descriptor> </descriptor>
</key>

这时,代码需要支持EF,所以引入如下NuGet包

Microsoft.AspNetCore.DataProtection Microsoft.AspNetCore.DataProtection.EntityFrameworkCore Microsoft.EntityFrameworkCore

Microsoft.EntityFrameworkCore.SqlServer

代码要换成EF方式持久化key,要注入EF的Context,然后注入数据保护对象时指明持久化的方式:

using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.DataProtection.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;var builder = WebApplication.CreateBuilder(args);builder.Services.AddDbContext<DataProtContext>(options =>options.UseSqlServer(builder.Configuration.GetConnectionString("DataProtDB")));
builder.Services.AddDataProtection().PersistKeysToDbContext<DataProtContext>();
var app = builder.Build();app.MapGet("/encrypt/{str}", (IDataProtectionProvider provider, ILogger<Program> logger, string str) =>
{var protector = provider.CreateProtector("a.b.c");var sec = protector.Protect(str);logger.LogInformation(sec);return "加密:" + sec;
});
app.MapGet("/decrypt/{sec}", (IDataProtectionProvider provider, ILogger<Program> logger, string sec) =>
{var protector = provider.CreateProtector("a.b.c");var str = protector.Unprotect(sec);logger.LogInformation(str);return "解密:" + str;
});app.Run();class DataProtContext : DbContext, IDataProtectionKeyContext
{public DbSet<DataProtectionKey> DataProtectionKeys { get; set; }public DataProtContext(DbContextOptions<DataProtContext> options): base(options){}
}

加密结果:

解密结果:

如果生成的加密串需要时效性,需要把生成的Protector转成TimeLimitedDataProtector来加解密,如下:

……
app.MapGet("/encrypt/{str}", (IDataProtectionProvider provider, ILogger<Program> logger, string str) =>
{var protector = provider.CreateProtector("a.b.c");var sec = protector.ToTimeLimitedDataProtector().Protect(str, TimeSpan.FromSeconds(30));logger.LogInformation(sec);return "加密:" + sec;
});
app.MapGet("/decrypt/{sec}", (IDataProtectionProvider provider, ILogger<Program> logger, string sec) =>
{var protector = provider.CreateProtector("a.b.c");var str = protector.ToTimeLimitedDataProtector().Unprotect(sec);logger.LogInformation(str);return "解密:" + str;
});……

如果加密串过期提交,报错如下:

.NET6之MiniAPI(十六):数据保护相关推荐

  1. .NET6之MiniAPI(十九):NLog

    在本系例文章的第八篇中,我们聊过官方的日志实现,即<.NET6之MiniAPI(八):日志>.但官方的日志功能更多是提供了一个实现基础,对于要求一个灵活,强大,方便的日志体系,官方的还是有 ...

  2. .NET6之MiniAPI(十八):OpenAPI swagger

    从本篇开始,介绍一些很不错的三方库,来丰富MiniAPI的使用. 在创建MiniAPI项目时,模板提供了一个是否启用OpenAPI的选项,足见这个三方库的优势和强大. OpenAPI为我们测试API提 ...

  3. .NET6之MiniAPI(十五):跨域CORS(下)

    前一篇的跨域请求的方式是松宽的方式,毕竟跨域有安全风险,应尽量少的允许访问必要资源,本篇分别从请求方法,请求头和请求凭据方面了解跨域设置. 请求方法: api项目,get,post是默认访问,这里只设 ...

  4. .NET6之MiniAPI(十四):跨域CORS(上)

    为了说明跨请求,创建了两个项目,一个mini api,端口是5001,另一个razor page项目,端口是5280.5280项目会在页面用ajax的方式来请求5001,形成跨域请求,由于是本地测试, ...

  5. .NET6之MiniAPI(十二):引入EntityFramewor

    说明:本篇重点说明MiniAPI引入EntityFramework,EF的使用不是本篇的重点 本篇是在MiniAPI中使用EntityFramework,所以先奉上创建数据的脚本,数据库是SQL Se ...

  6. .NET6之MiniAPI(十):基于策略的身份验证和授权

    JWT不管是基于角色,还是自定义策略,实现的步骤都是大同小异的,基于自定义策略的步骤如下: 1.appsettings.json中配置JWT参 2.添加身份认证和授权服务和中间件,并设置为策略模式和策 ...

  7. .NET6之MiniAPI(三十):结束篇(附链接)

    不知不觉来到了<.NET6之MiniAPI>的第三十篇,回顾之前的篇幅,主要涉及如下: HTTP请求,应答 Request 桂素伟,公众号:桂迹.NET6之MiniAPI(二):reque ...

  8. 计算机强制关机原理,解决PC常见问题 篇十六:究竟如何关机才是正确的姿势---关于“按电源键强制关机对硬件无危害”的...

    解决PC常见问题 篇十六:究竟如何关机才是正确的姿势---关于"按电源键强制关机对硬件无危害"的 2020-08-10 10:21:40 36点赞 186收藏 64评论 本文背景 ...

  9. 2021年大数据HBase(十六):HBase的协处理器(Coprocessor)

    全网最详细的大数据HBase文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 HBase的协处理器(Coprocessor) 一.起源 二 ...

最新文章

  1. 图标化java_java最小化到托盘显示图标实现
  2. 嵌入式处理器的体系架构与内核详解
  3. 百度社会化分享组件使用问题
  4. Python的底气,是从哪儿来的?
  5. 定了!苹果 10 亿美元收购英特尔调制解调器部门!
  6. 程序员:进不了大厂,就“永无出头之日”了?
  7. 菊子曰测试草稿{29C28FD771BA4B0D8693}
  8. typedef 的使用
  9. ngram模型中文语料实验step by step(3)-ngram模型的光滑处理
  10. android 高德amap开发二(地图操作)
  11. Mac电脑如何添加打印机?
  12. 如何用计算机求一个正数的算术平方根,《用计算器求一个正数的算术平方根》教学设计...
  13. Mindspore | lenet 模型代码
  14. shell 脚本中日期运算
  15. 虚幻4引擎开发使用感受
  16. ArrayList类的详解
  17. 【常见 Error Bug】Vivado仿真报错 ERROR: [XSIM 43-3322] 解决方法
  18. java libusb_libusb中断传输
  19. PTA 1027 Colors in Mars(读懂题目意思很重要!!)
  20. Animation动画效果

热门文章

  1. 移动web开发(一)——移动web开发必备知识
  2. linux 后台一直执行的sh
  3. centos 6.3安装libmcrypt-2.5.8不成功解决方案
  4. linux 去掉 ^M 的方法
  5. yum 下载RPM包而不进行安装
  6. 2016-2017-2学期《程序设计与数据结构》教学进程
  7. sql面试语句与后台调用js提示语句
  8. 指针04 - 零基础入门学习C语言44
  9. jQuery中this与$(this)区别
  10. Mac系统下Homebrew的安装和使用Homebrew安装python