ASP.NET Core 데이터 보호에 대한 비-DI 인식 시나리오Non-DI aware scenarios for Data Protection in ASP.NET Core

작성자: Rick AndersonBy Rick Anderson

ASP.NET Core, 데이터 보호, 종속성 주입, DataProtectionProvider 서비스 컨테이너에 추가 된, 종속 구성 요소에서 종속성 주입(DI)을 통해서 사용됩니다.The ASP.NET Core Data Protection system is normally added to a service container and consumed by dependent components via dependency injection (DI). 그러나 경우에 따라서는 이런 구성이 불가능한 경우도 있으며, 그 대표적인 사례가 기존 응용 프로그램에 데이터 보호 시스템을 추가하는 경우입니다.However, there are cases where this isn't feasible or desired, especially when importing the system into an existing app.

이러한 시나리오를 지원 하도록는 Microsoft.AspNetCore.DataProtection.Extensions 패키지는 구체적인 형식이 제공 DataProtectionProvider, 데이터 보호를 사용 하는 간단한 방법을 제공 DI에 의존 하지 않고 합니다.To support these scenarios, the Microsoft.AspNetCore.DataProtection.Extensions package provides a concrete type, DataProtectionProvider, which offers a simple way to use Data Protection without relying on DI. DataProtectionProvider 구현 입력 IDataProtectionProvider합니다.The DataProtectionProvider type implements IDataProtectionProvider. 생성 DataProtectionProvider 하기만 제공 하는 DirectoryInfo 다음 코드 예제와 같이 공급자의 암호화 키 저장 될 위치를 나타냅니다.Constructing DataProtectionProvider only requires providing a DirectoryInfo instance to indicate where the provider's cryptographic keys should be stored, as seen in the following code sample:

using System;
using System.IO;
using Microsoft.AspNetCore.DataProtection;

public class Program
{
    public static void Main(string[] args)
    {
        // Get the path to %LOCALAPPDATA%\myapp-keys
        var destFolder = Path.Combine(
            System.Environment.GetEnvironmentVariable("LOCALAPPDATA"),
            "myapp-keys");

        // Instantiate the data protection system at this folder
        var dataProtectionProvider = DataProtectionProvider.Create(
            new DirectoryInfo(destFolder));

        var protector = dataProtectionProvider.CreateProtector("Program.No-DI");
        Console.Write("Enter input: ");
        var input = Console.ReadLine();

        // Protect the payload
        var protectedPayload = protector.Protect(input);
        Console.WriteLine($"Protect returned: {protectedPayload}");

        // Unprotect the payload
        var unprotectedPayload = protector.Unprotect(protectedPayload);
        Console.WriteLine($"Unprotect returned: {unprotectedPayload}");

        Console.WriteLine();
        Console.WriteLine("Press any key...");
        Console.ReadKey();
    }
}

/*
 * SAMPLE OUTPUT
 *
 * Enter input: Hello world!
 * Protect returned: CfDJ8FWbAn6...ch3hAPm1NJA
 * Unprotect returned: Hello world!
 *
 * Press any key...
*/

기본적으로는 DataProtectionProvider 구체적인 형식 원시 키 자료를 암호화 하지 않습니다 전에 파일 시스템에 유지 합니다.By default, the DataProtectionProvider concrete type doesn't encrypt raw key material before persisting it to the file system. 이 시나리오를 네트워크 공유 및 데이터 보호 시스템 개발자 포인트 추론할 수 없습니다. 자동으로 적절 한 휴지 키 암호화 메커니즘을 지 원하는입니다.This is to support scenarios where the developer points to a network share and the Data Protection system can't automatically deduce an appropriate at-rest key encryption mechanism.

또한, 기본적으로 DataProtectionProvider 구체 형식은 앱을 격리 하지 않습니다.Additionally, the DataProtectionProvider concrete type doesn't isolate apps by default. 동일한 키 디렉터리를 가리키는 모든 응용 프로그램들은 매개 변수 용도 위해가 일치하기만 하면 페이로드를 공유할 수 있습니다.All apps using the same key directory can share payloads as long as their purpose parameters match.

DataProtectionProvider 생성자가 시스템의 동작을 조정 하는 데 사용할 수 있는 선택적 구성 콜백 허용 합니다.The DataProtectionProvider constructor accepts an optional configuration callback that can be used to adjust the behaviors of the system. 다음 예제를 명시적으로 호출 된 복원 격리를 보여 줍니다. SetApplicationName합니다.The sample below demonstrates restoring isolation with an explicit call to SetApplicationName. 이 샘플에는 자동으로 보관 되는 Windows DPAPI를 사용 하 여 키를 암호화 하는 시스템 구성 보여 줍니다.The sample also demonstrates configuring the system to automatically encrypt persisted keys using Windows DPAPI. 관련 된 모든 컴퓨터에 공유 인증서를 배포 하 고 시스템을 호출 하 여 인증서 기반 암호화를 사용 하도록 구성 하는 디렉터리는 UNC 공유를 가리키는 경우 지정할 수 있습니다 ProtectKeysWithCertificate합니다.If the directory points to a UNC share, you may wish to distribute a shared certificate across all relevant machines and to configure the system to use certificate-based encryption with a call to ProtectKeysWithCertificate.

using System;
using System.IO;
using Microsoft.AspNetCore.DataProtection;

public class Program
{
    public static void Main(string[] args)
    {
        // Get the path to %LOCALAPPDATA%\myapp-keys
        var destFolder = Path.Combine(
            System.Environment.GetEnvironmentVariable("LOCALAPPDATA"),
            "myapp-keys");

        // Instantiate the data protection system at this folder
        var dataProtectionProvider = DataProtectionProvider.Create(
            new DirectoryInfo(destFolder),
            configuration =>
            {
                configuration.SetApplicationName("my app name");
                configuration.ProtectKeysWithDpapi();
            });

        var protector = dataProtectionProvider.CreateProtector("Program.No-DI");
        Console.Write("Enter input: ");
        var input = Console.ReadLine();

        // Protect the payload
        var protectedPayload = protector.Protect(input);
        Console.WriteLine($"Protect returned: {protectedPayload}");

        // Unprotect the payload
        var unprotectedPayload = protector.Unprotect(protectedPayload);
        Console.WriteLine($"Unprotect returned: {unprotectedPayload}");

        Console.WriteLine();
        Console.WriteLine("Press any key...");
        Console.ReadKey();
    }
}

DataProtectionProvider 구체 형식의 인스턴스를 생성하는 것은 비용이 많이 드는 작업입니다.Instances of the DataProtectionProvider concrete type are expensive to create. 만약, 응용 프로그램이 이 형식의 인스턴스를 여러 개 관리하지만 모든 인스턴스가 동일한 키 저장소 디렉터리를 가리킨다면 응용 프로그램의 성능이 저하될 수 있습니다. If an app maintains multiple instances of this type and if they're all using the same key storage directory, app performance might degrade. DataProtectionProvider 형식을 사용할 때 권장되는 방식은 응용 프로그램 개발자가 이 형식의 인스턴스를 한 번만 생성한 다음, 해당 단일 참조를 가능한 여러 번 재사용하는 것입니다.If you use the DataProtectionProvider type, we recommend that you create this type once and reuse it as much as possible. DataProtectionProvider 형식 및 이 형식으로부터 생성된 모든 IDataProtector 의 인스턴스는 다중 호출자에 대해 스레드로부터 안전(Thread-Safe)합니다.The DataProtectionProvider type and all IDataProtector instances created from it are thread-safe for multiple callers.