在 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 中的資料,而且在過期時間之內加密解密操作都是安全的,如果你的密文要維持很長的時間,這種場景下建議自己實現 加密解密
邏輯。