如何在 ASP.Net Core 中實現(xiàn)數(shù)據(jù)保護API
本文轉(zhuǎn)載自微信公眾號「碼農(nóng)讀書 」,作者碼農(nóng)讀書 。轉(zhuǎn)載本文請聯(lián)系 碼農(nóng)讀書 公眾號。
在 ASP.Net Core 數(shù)據(jù)保護棧中提供了一種非常簡單的方法來加密API,從而保護數(shù)據(jù)的安全,通常落地的做法就是 數(shù)據(jù)加密 和 數(shù)據(jù)解密,這篇文章我們就來一起看看如何使用數(shù)據(jù)保護API。
理解加密和哈希
在安全領(lǐng)域,加密和hash是兩個非常重要的概念,常常被開發(fā)者混用,其實這是不對的,加密是用一種加密算法將一種數(shù)據(jù)轉(zhuǎn)換成另外一種數(shù)據(jù),同時也要注意,這是一種雙向操作,已加密的數(shù)據(jù)只能通過一個合適的密鑰去解密,加過密的數(shù)據(jù)又稱為密文,在如今的系統(tǒng)間通訊,數(shù)據(jù)加密還是非常簡單高效的。
相比之下,hash 是一種將 text 轉(zhuǎn)成 消息摘要 的技術(shù),要值得注意的是,hash值是唯一的,這就意味著不同的text文本不可能生成同一個 hash 值,而且還要注意的是,當(dāng) text 轉(zhuǎn)成了 hash 值之后,你很難再將 hash 值再還原成 text 文本。
總的來說,加密是一種雙向技術(shù),可以使用同一個密鑰對數(shù)據(jù)進行加密解密,hash是一種單向技術(shù),它可以將 text 轉(zhuǎn)成 消息摘要,而這個摘要很難再還原成原始text。
安裝 Microsoft.AspNetCore.DataProtection
要想使用 數(shù)據(jù)保護API, 可以使用 Visual Studio 2019 中的 NuGet package manager 可視化界面,還可以用 NuGet package manager console 在命令行窗口中鍵入如下命令。
- dotnet add package Microsoft.AspNetCore.DataProtection -Version 2.2.0
配置數(shù)據(jù)保護API
按照 ASP.NET Core 的默認(rèn)慣例,先將 DataProtection 注入到 ServiceCollection 中,如下代碼所示。
- public class Startup
- {
- // This method gets called by the runtime. Use this method to add services to the container.
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddControllers();
- services.AddDataProtection();
- }
- }
如果你想將加密和解密用到的 密鑰 單獨存放到文件系統(tǒng)中的話,可以在注入時稍微修改一下,如下代碼所示:
- public class Startup
- {
- // This method gets called by the runtime. Use this method to add services to the container.
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddControllers();
- services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(@"D:\IDG\Temp"));
- }
- }
值得注意的是,密鑰 是由 數(shù)據(jù)保護API 創(chuàng)建和維護,默認(rèn)情況下這個 key 的有效期是 90天,如果你有特殊需求,也可以自己指定 key 的有效期,如下代碼所示:
- public class Startup
- {
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddControllers();
- services.ConfigureDataProtection(dp =>
- {
- dp.PersistKeysToFileSystem(new DirectoryInfo(@"D:\IDG\Temp"));
- dp.SetDefaultKeyLifetime(TimeSpan.FromDays(7));
- });
- }
- }
你甚至可以使用一個證書來保護密鑰,也可以直接使用 Azure Key Valult 來存儲密鑰,如果想使用后者,可以用下面的代碼來配置。
- public class Startup
- {
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddControllers();
- services.AddDataProtection().PersistKeysToAzureBlobStorage(new Uri("Specify the Uri here"))
- .ProtectKeysWithAzureKeyVault("keyIdentifier", "clientId", "clientSecret");
- }
- }
數(shù)據(jù)加密
現(xiàn)在 數(shù)據(jù)保護API 已經(jīng)安裝并配置成功了,接下來看看如何在 Controller 中使用數(shù)據(jù)保護API。
- [ApiController]
- [Route("[controller]")]
- public class WeatherForecastController : ControllerBase
- {
- IDataProtector _protector;
- public WeatherForecastController(IDataProtectionProvider provider)
- {
- _protector = provider.CreateProtector(GetType().FullName);
- }
- [HttpGet]
- public string Get()
- {
- var protectedData = _protector.Protect("Hello World");
- return protectedData;
- }
- }
從圖中可以看到,HelloWorld 已經(jīng)被成功加密返回給到前端了,對了,為了能夠盡量可復(fù)用,可以單獨用一個幫助類來做 數(shù)據(jù)保護API 中的數(shù)據(jù)加密解密,如下代碼所示:
- public class DataProtectionHelper
- {
- private readonly IDataProtectionProvider _dataProtectionProvider;
- public DataProtectionHelper(IDataProtectionProvider dataProtectionProvider)
- {
- _dataProtectionProvider = dataProtectionProvider;
- }
- public string Encrypt(string textToEncrypt, string key)
- {
- return _dataProtectionProvider.CreateProtector(key).Protect(textToEncrypt);
- }
- public string Decrypt(string cipherText, string key)
- {
- return _dataProtectionProvider.CreateProtector(key).Unprotect(cipherText);
- }
- }
值得注意的是,上面的 Encrypt 和 Decrypt 方法的第二個參數(shù)是密鑰key,這樣的話 密鑰 的掌控權(quán)就在你的手上了。
數(shù)據(jù)保護API 使用起來還是非常簡單靈活的,使用這種方法來生成密文數(shù)據(jù)是一種非常好的方法,常見的場景太多了,比如:cookie,querystring 中的數(shù)據(jù),而且在過期時間之內(nèi)加密解密操作都是安全的,如果你的密文要維持很長的時間,這種場景下建議自己實現(xiàn) 加密解密 邏輯。
譯文鏈接:https://www.infoworld.com/article/3431139/how-to-use-the-data-protection-api-in-aspnet-core.html