在 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 中的数据,而且在过期时间之内加密解密操作都是安全的,如果你的密文要维持很长的时间,这种场景下建议自己实现 加密解密
逻辑。
**更多高质量干货:参见我的 GitHub: [csharptranslate] github.com/ctripxchuang/csharptranslate **