溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

ASP.NETCore中數(shù)據(jù)保護(hù)Data Protection的用法是怎樣的

發(fā)布時(shí)間:2021-09-16 16:22:12 來源:億速云 閱讀:171 作者:柒染 欄目:開發(fā)技術(shù)

這篇文章將為大家詳細(xì)講解有關(guān)ASP.NETCore中數(shù)據(jù)保護(hù)Data Protection的用法是怎樣的,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

 

API 接口 

ASP.NET Core Data Protectio 主要對(duì)普通開發(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 ,從命名來看,一個(gè)是加密,一個(gè)是解密。而他們的簽名都是傳入一個(gè)byte數(shù)組,這也就意味著他們可以加密和解密一切對(duì)象。返回的也是byte數(shù)組,也就是說在實(shí)際的使用過程中,我們應(yīng)該自己添加或者使用系統(tǒng)的一些擴(kuò)展方法來具體化我們的需求。 

我們?cè)倏匆幌翴DataProtectionProvider接口:

 namespace Microsoft.AspNetCore.DataProtection
{
 public interface IDataProtectionProvider
 {

  IDataProtector CreateProtector(string purpose);
 }
}

IDataProtectionProvider提供了一個(gè)方法,通過傳入一個(gè) purpose字符串(見后面詳細(xì)介紹)來生成一個(gè)IDataProtector接口對(duì)象。
 從這個(gè)接口的命名來看,它以Provider結(jié)尾,也就是說這部分我們可以實(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ì)模式,也可以說它是由微軟發(fā)明的,它不屬于23種設(shè)計(jì)模式中的一種,從功能上來看的話,應(yīng)該是工廠和策略的結(jié)合體。自ASP.NET 2.0開始,微軟就開始引入這種設(shè)計(jì)模式,最開始主要是用于實(shí)現(xiàn)應(yīng)用程序的配置的多個(gè)實(shí)現(xiàn)。比如開發(fā)者最熟悉的web.config中, 針對(duì)于數(shù)據(jù)庫連接字符串的配置, 還有二進(jìn)制,再比如XML啊等等很多,現(xiàn)在其他地方這種模式也用的越來越多起來。 

再來說一下CreateProtector方法簽名中的 purpose 這個(gè)字符串,在上一篇博文中為了讀者好理解,我把傳入的purpose說成可以理解為一個(gè)公鑰,其實(shí)這個(gè)說法是不嚴(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接口,就是說IDataProtector自身也可以再創(chuàng)建IDataProtector。 

舉個(gè)例子:我們?cè)谧鲆粋€(gè)消息通訊的系統(tǒng),在消息通訊的過程中,需要對(duì)用戶的會(huì)話進(jìn)行加密,我們使用CreateProtector("Security.BearerToken")加密。但是加密的時(shí)候并不能保證消息是不受信任的客戶端發(fā)過來的,所以想到了CreateProtector("username")來進(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方法用來對(duì)用戶密碼進(jìn)行哈希。 

具有生命周期限制的加密 

有些時(shí)候,我們需要一些具有過期或者到期時(shí)間的加密字符串,比如一個(gè)用戶在找回密碼的時(shí)候,我們向用戶的郵箱發(fā)送一封帶有重置命令的一封郵件,這個(gè)重置命令就需要有一個(gè)過期時(shí)間了,超過這個(gè)過期時(shí)間后就失效,在以前我們可能需要向數(shù)據(jù)庫存儲(chǔ)一個(gè)時(shí)間來標(biāo)記發(fā)送時(shí)間,然后再解密對(duì)比和數(shù)據(jù)庫的時(shí)間差來驗(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è)重載方法用來設(shè)定帶有生命周期的加密方法,用戶可以通過Date TimeOffset,TimeSpan等參數(shù)來設(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í)候,在上一篇博文的末尾也提到過,下面就來看一下具體怎么配置的吧。 

上篇文章已經(jīng)提到過,我們通過以下方式來把 Data Protection 注冊(cè)到服務(wù)中:

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

其中AddDataProtection 返回的是一個(gè) IDataProtectionBuilder 接口,這個(gè)接口提供了一個(gè)擴(kuò)展方法PersistKeysToFileSystem() 來存儲(chǔ)私鑰。可以通過它傳入一個(gè)路徑來指定私鑰存儲(chǔ)的位置:

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

}

可以傳入一個(gè)共享文件夾,來存儲(chǔ)私鑰,這樣在不同機(jī)器的私鑰就可以保存到一個(gè)位置了??梢酝ㄟ^此種方式在分布式部署的時(shí)候,隔離開了機(jī)器的差異化。
 如果你覺得不安全,還可以配置一個(gè)X.509證書來,進(jìn)行加密:

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

上篇文章講過,Data Protection 的默認(rèn)保存時(shí)間是90天,你可以通過以下方式來修改默認(rèn)的保存時(shí)間:

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

默認(rèn)情況下,即使使用相同的物理密鑰庫,Data Protection 也會(huì)把不同的應(yīng)用程序隔離開,因?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)用程序生成密鑰,或者是說我只有一個(gè)程序用來生成或者管理密鑰,其他程序只是負(fù)責(zé)讀的話,那么可以這樣:

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

修改加密算法 

可以使用UseCryptographicAlgorithms方法來修改ASP.NET Core Data Protection的默認(rèn)加密算法,如下:

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

關(guān)于ASP.NETCore中數(shù)據(jù)保護(hù)Data Protection的用法是怎樣的就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI