Home  >  Article  >  Backend Development  >  ASP.NET Core Data Protection

ASP.NET Core Data Protection

高洛峰
高洛峰Original
2016-12-26 10:48:371798browse

API interface

ASP.NET Core Data Protectio mainly provides two interfaces for ordinary developers, IDataProtectionProvider and IDataProtector.
Let’s first take a look at the relationship between these two interfaces:

namespace Microsoft.AspNetCore.DataProtection
{
 //
 // 摘要:
 //  An interface that can provide data protection services.
 public interface IDataProtector : IDataProtectionProvider
 {
 
  byte[] Protect(byte[] plaintext);
 
  byte[] Unprotect(byte[] protectedData);
 }
}

As you can see, IDataProtector inherits from IDataProtectionProvider and provides two methods, Protect and Unprotect, from the naming point of view , one is encryption and the other is decryption. Their signatures are passed in a byte array, which means they can encrypt and decrypt all objects. What is returned is also a byte array, which means that in actual use, we should add it ourselves or use some extension methods of the system to specify our needs.

Let’s take a look at the IDataProtectionProvider interface again:

namespace Microsoft.AspNetCore.DataProtection
{
 public interface IDataProtectionProvider
 {
 
  IDataProtector CreateProtector(string purpose);
 }
}

IDataProtectionProvider provides a method to generate a purpose string by passing in a purpose string (see details below) An IDataProtector interface object.
Judging from the naming of this interface, it ends with Provider, which means that in this part we can implement our own set of encryption and decryption things.

When we read the source code of Microsoft projects, we often look at some objects ending with xxxxProvider. So what are its responsibilities and what role does it play?
In fact, this is a design pattern specially designed by Microsoft for ASP.NET, called Provider Model design pattern. It can also be said that it was invented by Microsoft. It does not belong to one of the 23 design patterns. From a functional point of view If so, it should be a combination of factory and strategy. Microsoft has introduced this design pattern since ASP.NET 2.0, initially mainly for implementing multiple implementations of application configuration. For example, web.config, which is most familiar to developers, is for the configuration of database connection strings, as well as binary, XML, etc. This mode is now used more and more in other places.

Let’s talk about the purpose string in the CreateProtector method signature. In the previous blog post, for the sake of easier understanding for readers, I said the incoming purpose can be understood as a public key. In fact, this The statement is not rigorous and can be understood as a logo indicating the purpose of the current Protector.

When using IDataProtector, you will find that it also has some extension methods located under the Microsoft.AspNetCore.DataProtection namespace:

public static class DataProtectionCommonExtensions
{
 public static IDataProtector CreateProtector(this IDataProtectionProvider provider, IEnumerable<string> purposes);
 
 public static IDataProtector CreateProtector(this IDataProtectionProvider provider, string purpose, params string[] subPurposes);
 
 public static IDataProtector GetDataProtector(this IServiceProvider services, IEnumerable<string> purposes);
 
 public static IDataProtector GetDataProtector(this IServiceProvider services, string purpose, params string[] subPurposes);
 
 public static string Protect(this IDataProtector protector, string plaintext);
 
 public static string Unprotect(this IDataProtector protector, string protectedData);
}


As you can see, CreateProtector also provides methods that can pass multiple purposes (IEnumerable, params string[]). Why is there such a need?

In fact, DataProtector has a hierarchical structure. Look at the IDataProtector interface again. It also implements the IDataProtectionProvider interface, which means that IDataProtector itself can also create IDataProtector.

For example: We are working on a message communication system. During the message communication process, the user's session needs to be encrypted. We use CreateProtector("Security.BearerToken") to encrypt. However, when encrypting, there is no guarantee that the message is sent by an untrusted client, so I thought of CreateProtector("username") for encryption. At this time, if there is a user named "Security.BearerToken", then It conflicts with another Protector that uses Security.BearerToken as the identifier, so we can use
CreateProtector([ “Security.BearerToken”, “User: username” ]). It is equivalent to
provider.CreateProtector("Security.BearerToken).CreateProtector("User: username"). It means first creating a Protector called "Security.BearerToken", and then creating a Protector named "User:" under purpose1. username" Protector.

User password hash

A KeyDerivation.Pbkdf2 method is provided under the Microsoft.AspNetCore.Cryptography.KeyDerivation namespace to use the user password Hash.

Encryption with life cycle restrictions

Sometimes, we need some encrypted strings with expiration or expiration time, such as a user looking for When returning the password, we send an email with a reset command to the user's mailbox. This reset command needs to have an expiration time. After this expiration time, it will become invalid. In the past, we might have to send a request to the database. Store a time to mark the sending time, and then decrypt and compare the time difference with the database to verify

Now we don’t need to do this. ASP.NET Core provides an interface called ITimeLimitedDataProtector by default. Let’s first do this. Take a look at the definition of this interface:

CreateProtector(string purpose) : ITimeLimitedDataProtector This API is similar to the existing IDataProtectionProvider.CreateProtector in that it can be used to create purpose chains from a root time-limited protector.
Protect(byte[] plaintext, DateTimeOffset expiration) : byte[]
Protect(byte[] plaintext, TimeSpan lifetime) : byte[]
Protect(byte[] plaintext) : byte[]
Protect(string plaintext, DateTimeOffset expiration) : string
Protect(string plaintext, TimeSpan lifetime) : string
Protect(string plaintext) : string


ITimeLimitedDataProtector provides several overloaded methods for setting encryption methods with life cycles. Users You can set the time through Date TimeOffset, TimeSpan and other parameters.

has corresponding encryption and corresponding decryption methods. Interested students can take a look at them here. Official documentation.

Configuring Data Protection

在我们的 ASP.NET Core 运行的时候,系统会基于当前机器的运行环境默认配置一些关于 Data Protection 的东西,但是有些时候可能需要对这些配置做一些改变,比如在分布式部署的时候,在上一篇博文的末尾也提到过,下面就来看一下具体怎么配置的吧。 

上篇文章已经提到过,我们通过以下方式来把 Data Protection 注册到服务中:

public void ConfigureServices(IServiceCollection services)
{
 services.AddDataProtection();
}

   


其中AddDataProtection 返回的是一个 IDataProtectionBuilder 接口,这个接口提供了一个扩展方法PersistKeysToFileSystem() 来存储私钥。可以通过它传入一个路径来指定私钥存储的位置:

public void ConfigureServices(IServiceCollection services)
{
 services.AddDataProtection()
  .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"));
 
}

   

可以传入一个共享文件夹,来存储私钥,这样在不同机器的私钥就可以保存到一个位置了。可以通过此种方式在分布式部署的时候,隔离开了机器的差异化。
 如果你觉得不安全,还可以配置一个X.509证书来,进行加密:

public void ConfigureServices(IServiceCollection services)
{
 services.AddDataProtection()
  .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"))
  .ProtectKeysWithCertificate("thumbprint");
}

   


上篇文章讲过,Data Protection 的默认保存时间是90天,你可以通过以下方式来修改默认的保存时间:

public void ConfigureServices(IServiceCollection services)
{
 services.AddDataProtection()
  .SetDefaultKeyLifetime(TimeSpan.FromDays(14));
}

   


默认情况下,即使使用相同的物理密钥库,Data Protection 也会把不同的应用程序隔离开,因为这样可以防止从一个应用程序获取另外一个应用程序的密钥。所以如果是相同的应用程序,可以设置相同的应用程序名称:

public void ConfigureServices(IServiceCollection services)
{
 services.AddDataProtection()
  .SetApplicationName("my application");
}

   


有时候需要禁用应用程序生成密钥,或者是说我只有一个程序用来生成或者管理密钥,其他程序只是负责读的话,那么可以这样:

 
public void ConfigureServices(IServiceCollection services)
{
 services.AddDataProtection()
  .DisableAutomaticKeyGeneration();
}

   


修改加密算法 

可以使用UseCryptographicAlgorithms方法来修改ASP.NET Core Data Protection的默认加密算法,如下:

services.AddDataProtection()
.UseCryptographicAlgorithms(new AuthenticatedEncryptionSettings()
{
 EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
 ValidationAlgorithm = ValidationAlgorithm.HMACSHA256
});

   


总结:

本篇主要是介绍了一些常用的API, 下篇介绍一些高级的用法。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持PHP中文网。

更多ASP.NET Core 数据保护(Data Protection)相关文章请关注PHP中文网!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn