ASP.NET Core 數(shù)據(jù)保護(hù)(Data Protection)中篇
前言
上篇主要是對(duì) ASP.NET Core 的 Data Protection 做了一個(gè)簡(jiǎn)單的介紹,本篇主要是介紹一下API及使用方法。
API 接口
ASP.NET Core Data Protectio 主要對(duì)普通開(kāi)發(fā)人員提供了兩個(gè)接口,IDataProtectionProvider 和 IDataProtector。
我們先看一下這兩個(gè)接口的關(guān)系:
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 ,并且提供了兩個(gè)方法 Protect 和 Unprotect ,從命名來(lái)看,一個(gè)是加密,一個(gè)是解密。而他們的簽名都是傳入一個(gè)byte數(shù)組,這也就意味著他們可以加密和解密一切對(duì)象。返回的也是byte數(shù)組,也就是說(shuō)在實(shí)際的使用過(guò)程中,我們應(yīng)該自己添加或者使用系統(tǒng)的一些擴(kuò)展方法來(lái)具體化我們的需求。
我們?cè)倏匆幌翴DataProtectionProvider接口:
namespace Microsoft.AspNetCore.DataProtection { public interface IDataProtectionProvider { IDataProtector CreateProtector(string purpose); } }
IDataProtectionProvider提供了一個(gè)方法,通過(guò)傳入一個(gè) purpose字符串(見(jiàn)后面詳細(xì)介紹)來(lái)生成一個(gè)IDataProtector接口對(duì)象。
從這個(gè)接口的命名來(lái)看,它以Provider結(jié)尾,也就是說(shuō)這部分我們可以實(shí)現(xiàn)自己的一套加解密的東西。
我們?cè)陂喿x微軟項(xiàng)目的源代碼的時(shí)候,經(jīng)??匆恍┮詘xxxProvider結(jié)尾的對(duì)象,那么它的職責(zé)是什么,同時(shí)扮演什么樣的角色呢?
其實(shí)這是微軟專門為ASP.NET設(shè)計(jì)的一個(gè)設(shè)計(jì)模式,叫Provider Model設(shè)計(jì)模式,也可以說(shuō)它是由微軟發(fā)明的,它不屬于23種設(shè)計(jì)模式中的一種,從功能上來(lái)看的話,應(yīng)該是工廠和策略的結(jié)合體。自ASP.NET 2.0開(kāi)始,微軟就開(kāi)始引入這種設(shè)計(jì)模式,最開(kāi)始主要是用于實(shí)現(xiàn)應(yīng)用程序的配置的多個(gè)實(shí)現(xiàn)。比如開(kāi)發(fā)者最熟悉的web.config中, 針對(duì)于數(shù)據(jù)庫(kù)連接字符串的配置, 還有二進(jìn)制,再比如XML啊等等很多,現(xiàn)在其他地方這種模式也用的越來(lái)越多起來(lái)。
再來(lái)說(shuō)一下CreateProtector方法簽名中的 purpose 這個(gè)字符串,在上一篇博文中為了讀者好理解,我把傳入的purpose說(shuō)成可以理解為一個(gè)公鑰,其實(shí)這個(gè)說(shuō)法是不嚴(yán)謹(jǐn)?shù)模梢岳斫鉃橐粋€(gè)標(biāo)識(shí),指示當(dāng)前Protector的用途。
在使用IDataProtector的時(shí)候,會(huì)發(fā)現(xiàn)它還有一些擴(kuò)展方法位于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還提供了可以傳多個(gè)purpose的方法(IEnumerable,params string[]),為什么會(huì)有這種需求呢?
其實(shí)DataProtector是有層次結(jié)構(gòu)的,再看一下IDataProtector接口,它自身也實(shí)現(xiàn)了IDataProtectionProvider接口,就是說(shuō)IDataProtector自身也可以再創(chuàng)建IDataProtector。
舉個(gè)例子:我們?cè)谧鲆粋€(gè)消息通訊的系統(tǒng),在消息通訊的過(guò)程中,需要對(duì)用戶的會(huì)話進(jìn)行加密,我們使用CreateProtector("Security.BearerToken")加密。但是加密的時(shí)候并不能保證消息是不受信任的客戶端發(fā)過(guò)來(lái)的,所以想到了CreateProtector("username")來(lái)進(jìn)行加密,這個(gè)時(shí)候假如有一個(gè)用戶的用戶名叫“Security.BearerToken”,那么就和另外一個(gè)使用Security.BearerToken作為標(biāo)示的 Protector 沖突了,所以我們可以使用
CreateProtector([ “Security.BearerToken”, “User: username” ])這種方式。它相當(dāng)于
provider.CreateProtector(“Security.BearerToken).CreateProtector(“User: username”)。 意思就是先創(chuàng)建一個(gè)Protector叫“Security.BearerToken”,然后再在purpose1下創(chuàng)建一個(gè)名為“User: username”的Protector。
用戶密碼哈希
在Microsoft.AspNetCore.Cryptography.KeyDerivation命名空間下提供了一個(gè)KeyDerivation.Pbkdf2方法用來(lái)對(duì)用戶密碼進(jìn)行哈希。
具有生命周期限制的加密
有些時(shí)候,我們需要一些具有過(guò)期或者到期時(shí)間的加密字符串,比如一個(gè)用戶在找回密碼的時(shí)候,我們向用戶的郵箱發(fā)送一封帶有重置命令的一封郵件,這個(gè)重置命令就需要有一個(gè)過(guò)期時(shí)間了,超過(guò)這個(gè)過(guò)期時(shí)間后就失效,在以前我們可能需要向數(shù)據(jù)庫(kù)存儲(chǔ)一個(gè)時(shí)間來(lái)標(biāo)記發(fā)送時(shí)間,然后再解密對(duì)比和數(shù)據(jù)庫(kù)的時(shí)間差來(lái)驗(yàn)證。
現(xiàn)在我們不需要這么做了,ASP.NET Core 默認(rèn)提供了一個(gè)接口叫 ITimeLimitedDataProtector ,我們先看一下這個(gè)接口的定義:
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提供了數(shù)個(gè)重載方法用來(lái)設(shè)定帶有生命周期的加密方法,用戶可以通過(guò)Date TimeOffset,TimeSpan等參數(shù)來(lái)設(shè)置時(shí)間。
有對(duì)應(yīng)的加密,就有相對(duì)應(yīng)的解密方法,在這里就不詳細(xì)介紹了。有興趣的同學(xué)可以去看一下官方文檔。
配置數(shù)據(jù)保護(hù)
在我們的 ASP.NET Core 運(yùn)行的時(shí)候,系統(tǒng)會(huì)基于當(dāng)前機(jī)器的運(yùn)行環(huán)境默認(rèn)配置一些關(guān)于 Data Protection 的東西,但是有些時(shí)候可能需要對(duì)這些配置做一些改變,比如在分布式部署的時(shí)候,在上一篇博文的末尾也提到過(guò),下面就來(lái)看一下具體怎么配置的吧。
上篇文章已經(jīng)提到過(guò),我們通過(guò)以下方式來(lái)把 Data Protection 注冊(cè)到服務(wù)中:
public void ConfigureServices(IServiceCollection services) { services.AddDataProtection(); }
其中AddDataProtection 返回的是一個(gè) IDataProtectionBuilder 接口,這個(gè)接口提供了一個(gè)擴(kuò)展方法PersistKeysToFileSystem() 來(lái)存儲(chǔ)私鑰。可以通過(guò)它傳入一個(gè)路徑來(lái)指定私鑰存儲(chǔ)的位置:
public void ConfigureServices(IServiceCollection services) { services.AddDataProtection() .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\")); }
可以傳入一個(gè)共享文件夾,來(lái)存儲(chǔ)私鑰,這樣在不同機(jī)器的私鑰就可以保存到一個(gè)位置了。可以通過(guò)此種方式在分布式部署的時(shí)候,隔離開(kāi)了機(jī)器的差異化。
如果你覺(jué)得不安全,還可以配置一個(gè)X.509證書(shū)來(lái),進(jìn)行加密:
public void ConfigureServices(IServiceCollection services) { services.AddDataProtection() .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\")) .ProtectKeysWithCertificate("thumbprint"); }
上篇文章講過(guò),Data Protection 的默認(rèn)保存時(shí)間是90天,你可以通過(guò)以下方式來(lái)修改默認(rèn)的保存時(shí)間:
public void ConfigureServices(IServiceCollection services) { services.AddDataProtection() .SetDefaultKeyLifetime(TimeSpan.FromDays(14)); }
默認(rèn)情況下,即使使用相同的物理密鑰庫(kù),Data Protection 也會(huì)把不同的應(yīng)用程序隔離開(kāi),因?yàn)檫@樣可以防止從一個(gè)應(yīng)用程序獲取另外一個(gè)應(yīng)用程序的密鑰。所以如果是相同的應(yīng)用程序,可以設(shè)置相同的應(yīng)用程序名稱:
public void ConfigureServices(IServiceCollection services) { services.AddDataProtection() .SetApplicationName("my application"); }
有時(shí)候需要禁用應(yīng)用程序生成密鑰,或者是說(shuō)我只有一個(gè)程序用來(lái)生成或者管理密鑰,其他程序只是負(fù)責(zé)讀的話,那么可以這樣:
public void ConfigureServices(IServiceCollection services) { services.AddDataProtection() .DisableAutomaticKeyGeneration(); }
修改加密算法
可以使用UseCryptographicAlgorithms方法來(lái)修改ASP.NET Core Data Protection的默認(rèn)加密算法,如下:
services.AddDataProtection() .UseCryptographicAlgorithms(new AuthenticatedEncryptionSettings() { EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC, ValidationAlgorithm = ValidationAlgorithm.HMACSHA256 });
總結(jié):
本篇主要是介紹了一些常用的API, 下篇介紹一些高級(jí)的用法。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- win10下ASP.NET Core部署環(huán)境搭建步驟
- asp.net core實(shí)現(xiàn)文件上傳功能
- ASP.NET Core配置教程之讀取配置信息
- ASP.NET Core集成微信登錄
- Linux(Ubuntu)下搭建ASP.NET Core環(huán)境
- 云服務(wù)器下搭建ASP.NET Core環(huán)境
- ASP.NET Core 1.0實(shí)現(xiàn)郵件發(fā)送功能
- ASP.NET Core MVC 配置全局路由前綴
- ASP.NET Core 數(shù)據(jù)保護(hù)(Data Protection)上篇
- 解決asp.net core在輸出中文時(shí)亂碼的問(wèn)題
相關(guān)文章
基于自定義Unity生存期模型PerCallContextLifeTimeManager的問(wèn)題
本篇文章小編將為大家介紹,基于自定義Unity生存期模型PerCallContextLifeTimeManager的問(wèn)題。需要的朋友參考下2013-04-04ASP.NET MVC中將控制器分離到類庫(kù)的實(shí)現(xiàn)
這篇文章主要介紹了ASP.NET MVC中將控制器分離到類庫(kù)的實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2015-06-06.NET使用.NET Core CLI開(kāi)發(fā)應(yīng)用程序
這篇文章主要為大家詳細(xì)介紹了.NET使用.NET Core CLI開(kāi)發(fā)應(yīng)用程序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08.NET Core對(duì)象池的應(yīng)用:擴(kuò)展篇
本文主要講解.NET Core對(duì)象池的池化集合、池化StringBuilder、ArrayPool<T>以及MemoryPool<T>,需要了解的小伙伴可以多學(xué)習(xí)這篇文章,相信可以幫助到你2021-09-09.NET程序集引用COM組件MSScriptControl遇到問(wèn)題的解決方法
這篇文章主要為大家詳細(xì)介紹了.NET程序集引用COM組件MSScriptControl遇到問(wèn)題的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01IIS7偽靜態(tài)web.config配置的方法和規(guī)則
本文主要介紹IIS7上配置偽靜態(tài)的超簡(jiǎn)單的新方法,安裝URLRewrite插件,配置web.config即可。2016-04-04ASP.NET Core文件上傳與下載實(shí)例(多種上傳方式)
下面小編就為大家分享一篇ASP.NET Core文件上傳與下載實(shí)例(多種上傳方式),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01