如何在 ASP.Net Core 中實現數據保護API
本文轉載自微信公眾號「碼農讀書 」,作者碼農讀書 。轉載本文請聯系 碼農讀書 公眾號。
在 ASP.Net Core 數據保護棧中提供了一種非常簡單的方法來加密API,從而保護數據的安全,通常落地的做法就是 數據加密 和 數據解密,這篇文章我們就來一起看看如何使用數據保護API。
理解加密和哈希
在安全領域,加密和hash是兩個非常重要的概念,常常被開發者混用,其實這是不對的,加密是用一種加密算法將一種數據轉換成另外一種數據,同時也要注意,這是一種雙向操作,已加密的數據只能通過一個合適的密鑰去解密,加過密的數據又稱為密文,在如今的系統間通訊,數據加密還是非常簡單高效的。
相比之下,hash 是一種將 text 轉成 消息摘要 的技術,要值得注意的是,hash值是唯一的,這就意味著不同的text文本不可能生成同一個 hash 值,而且還要注意的是,當 text 轉成了 hash 值之后,你很難再將 hash 值再還原成 text 文本。
總的來說,加密是一種雙向技術,可以使用同一個密鑰對數據進行加密解密,hash是一種單向技術,它可以將 text 轉成 消息摘要,而這個摘要很難再還原成原始text。
安裝 Microsoft.AspNetCore.DataProtection
要想使用 數據保護API, 可以使用 Visual Studio 2019 中的 NuGet package manager 可視化界面,還可以用 NuGet package manager console 在命令行窗口中鍵入如下命令。
- dotnet add package Microsoft.AspNetCore.DataProtection -Version 2.2.0
配置數據保護API
按照 ASP.NET Core 的默認慣例,先將 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();
- }
- }
如果你想將加密和解密用到的 密鑰 單獨存放到文件系統中的話,可以在注入時稍微修改一下,如下代碼所示:
- 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"));
- }
- }
值得注意的是,密鑰 是由 數據保護API 創建和維護,默認情況下這個 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");
- }
- }
數據加密
現在 數據保護API 已經安裝并配置成功了,接下來看看如何在 Controller 中使用數據保護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 已經被成功加密返回給到前端了,對了,為了能夠盡量可復用,可以單獨用一個幫助類來做 數據保護API 中的數據加密解密,如下代碼所示:
- 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 方法的第二個參數是密鑰key,這樣的話 密鑰 的掌控權就在你的手上了。
數據保護API 使用起來還是非常簡單靈活的,使用這種方法來生成密文數據是一種非常好的方法,常見的場景太多了,比如:cookie,querystring 中的數據,而且在過期時間之內加密解密操作都是安全的,如果你的密文要維持很長的時間,這種場景下建議自己實現 加密解密 邏輯。
譯文鏈接:https://www.infoworld.com/article/3431139/how-to-use-the-data-protection-api-in-aspnet-core.html