为什么需要数据保护
Web
应用程序中经常需要存储一些敏感数据(如用户密码),Windows
系统为桌面程序提供了DPAPI
用来使用,但是并不适用于Web
系统。ASP.NET Core
提供了一套简单易用的API
用来保护数据
ASP.NET Core 中,数据保护主要是用来给服务端设计的,用来替换ASP.NET 1.x-4.x中的,machineKey主要是用来保证使用Form身份验证时Cookie数据的加密解密,以确保不会被修改。或者ViewState数据的加密解密不被篡改,以及对session状态标识进行验证
最简单的示例
public class MyClass
{
readonly IDataProtector protector;
public MyClass(IDataProtectionProvider provider)
{
protector = provider.CreateProtector(nameof(MyClass));
}
public void RunSample()
{
string testStr = "Hello World";
// 加密
string protectedPayload = protector.Protect(testStr);
Console.WriteLine($"Protect returned: {protectedPayload}");
Console.WriteLine("=========================================");
// 解密
string unprotectedPayload = protector.Unprotect(protectedPayload);
Console.WriteLine($"Unprotect returned: {unprotectedPayload}");
}
}
[TestMethod()]
public void Sample_01()
{
// 添加数据保护到服务中
var serviceCollection = new ServiceCollection();
serviceCollection.AddDataProtection();
var services = serviceCollection.BuildServiceProvider();
// 从DI中创建一个MyClass的实例
var instance = ActivatorUtilities.CreateInstance<MyClass>(services);
instance.RunSample();
Assert.IsTrue(true);
}
在CreateProtector(nameof(MyClass))
中,参数“nameof(MyClass)
”可以理解为一个公钥或一个标识,指示当前Protector的用途。因为ASP.NET Core Data Protection 是非对称加密,所以系统中应该还有一个密钥,此处的密钥 ASP.NET Core 在系统内部帮你维护了,每一台机器都有一个自有的私钥
私钥存储
- 如果程序寄宿在
Microsoft Azure
下,存储在“%HOME%\ASP.NET\DataProtection-Keys”
文件夹 - 如果程序寄宿在
IIS
下,它被保存在HKLM
注册表的ACLed
特殊注册表键,并且只有工作进程可以访问,它使用windows
的DPAPI
加密 - 如果当前用户可用,即
win10
或者win7
中,它存储在%LOCALAPPDATA%\ASP.NET\DataProtection-Keys”
文件夹,同样使用的windows
的DPAPI
加密 - 如果这些都不符合,那么也就是私钥是没有被持久化的,也就是说当进程关闭的时候,生成的私钥就丢失了
私钥文件示例
<?xml version="1.0" encoding="utf-8"?>
<key id="bf2f4417-10fa-4d4d-ba61-b91c041029e0" version="1">
<creationDate>2021-03-08T02:18:08.641323Z</creationDate>
<activationDate>2021-03-09T09:07:57.9935838Z</activationDate>
<expirationDate>2021-06-06T02:18:08.5176468Z</expirationDate>
<descriptor deserializerType="Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60">
<descriptor>
<encryption algorithm="AES_256_CBC" />
<validation algorithm="HMACSHA256" />
<encryptedSecret decryptorType="Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiXmlDecryptor, Microsoft.AspNetCore.DataProtection, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60" xmlns="http://schemas.asp.net/2015/03/dataProtection">
<encryptedKey xmlns="">
<!-- This key is encrypted with Windows DPAPI. -->
<value>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAdzyZbq38yUupe39PhMdBEAAAAAACAAAAAAAQZgAAAAEAACAAAACYrALB9ricGU/5Y6iOanIlQjSCb548eBxAWafTbwxtLAAAAAAOgAAAAAIAACAAAADd6x5zXIP/VC6r1Y5ZAf74uL/+lc68ilrliN7T8dGhYVABAAD0qlvH4LDPjhr3R9WTjP+mOJZrrtt8clI91ULbNPDN2bgwM7ibkICFOLVr9AkwMpRzP+etArhuXbIhH6jzdv9aoAjAcQsQtg37LSlWBI3TFmTtz53nHzIxmfgUuPS23sLjHc7KTBo9+DPHy5BT3qm21y8EDoQ8ehj6WqqwvaEkThRXcG5Kst5HzBbIgeRXSrSprjIeja0uhJpFJOAzOr5ngeoRG4tKfs6VMZMIU9IMbukbuGSC/JoUMR5yzavT/Yi+Cr9x9eeIewDOKzRIaq3wIkYIybhOJxZm5MMgV3A4j4nKSSN0jcW6hXee5ksdywsPKquK5E5fz/jY6bVc9Sj1DV+A6IN6MAjstQzYpZ6CIjFJwgwD7OpD9G/JmlwRNhB/TnNWKAW+4duXYEgKADWA4ZVg2riaYYphPbEmz5RXnphN+C6OEDozguAsW60Z2DJAAAAAPxkE7aqhWgiAk2Fxf8w1yZ6ZMkBSXe/b655jsvfLl6asBUStynk08vPaw5YsD61VyRNp/s8lRjrfwyHpTGrxOw==</value>
</encryptedKey>
</encryptedSecret>
</descriptor>
</descriptor>
</key>
文件包含一个创建日期,一个过期日期。间隔为90天,当90天之后密钥就会失效,系统将自动生成一个新的密钥并设置新的密钥作为活动的密钥。只要已过期的密钥还存在于系统上,仍然可以解密任何受保护的数据