日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

.NET6之MiniAPI(十六):数据保护

發布時間:2023/12/4 asp.net 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .NET6之MiniAPI(十六):数据保护 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

對于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(十六):数据保护的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。