ASP.NET 코어 데이터 보호(데이터 보호 클 러 스 터 필드)다음 편
연결[중편]일부 장면 에서 우 리 는 ASP.NET Core 의 암호 화 방법 을 확장 하여 우리 의 수요 에 적응 해 야 한다.이 럴 때 일부 Core 가 제공 하 는 고급 기능 을 사용 해 야 한다.
본 고 는 클 러 스 터 장면 에서 가끔 우 리 는 자신의 방법 을 실현 하여 Data Protection 을 분포 식 으로 배치 해 야 한다 고 열거 했다.
암호 화 확장
IAuthenticated Encryptor 와 IAuthenticated Encryptor Descriptor
IAuthenticatedEncryptor 는 Data Protection 이 암호 화 시스템 을 구축 하 는 기본 적 인 인터페이스 입 니 다.
일반적인 상황 에서 다음 키 는 IAuthenticatedEncryptor,IAuthenticatedEncryptor 에 대응 하여 암호 화 작업 에 사용 할 비밀 키 재료 와 필요 한 암호 화 알고리즘 정보 등 을 봉인 합 니 다.
다음은 IAuthenticatedEncryptor 인터페이스 에서 제공 하 는 두 가지 api 방법 입 니 다.
Decrypt(ArraySegment
Encrypt(ArraySegment
그 중에서 인터페이스 에 있 는 매개 변 수 는 addition al AuthenticatedData 는 암호 화 를 구축 할 때 제공 하 는 부속 정 보 를 나타 낸다.
IAuthenticatedEncryptor Descriptor 인 터 페 이 스 는 형식 정 보 를 포함 하 는 IAuthenticatedEncryptor 인 스 턴 스 를 만 드 는 방법 을 제공 합 니 다.
CreateEncryptorInstance() : IAuthenticatedEncryptor
ExportToXml() : XmlSerializedDescriptorInfo
키 관리 확장
키 시스템 관리 에서 다음 속성 을 포함 하 는 기본 인터페이스 IKey 를 제공 합 니 다.
Activation
creation
expiration dates
Revocation status
Key identifier (a GUID)
IKey 는 IAuthenticatedEncryptor 인 스 턴 스 를 만 드 는 방법 인 Create Encryptor Instance 도 제공 했다.
IKeyManager 인 터 페 이 스 는 저장,검색 작업 등 키 를 조작 하 는 일련의 방법 을 제공 합 니 다.그 가 제공 한 고급 조작 은 다음 과 같다.
•키 를 만 들 고 영구적 으로 저장 합 니 다.
•저장 소 에서 모든 Key 가 져 오기
•저장 소 에 저 장 된 하나 이상 의 키 를 취소 합 니 다.
XmlKeyManager
일반적으로 개발 자 들 은 키 관리 자 를 정의 하 는 데 서 IKeyManager 를 실현 할 필요 가 없다.시스템 에서 기본적으로 제공 하 는 XmlKeyManager 클래스 를 사용 할 수 있 습 니 다.
XML KeyManager 는 IKeyManager 를 구체 적 으로 실현 하 는 클래스 로 매우 유용 한 방법 을 제공 합 니 다.
public sealed class XmlKeyManager : IKeyManager, IInternalXmlKeyManager
{
public XmlKeyManager(IXmlRepository repository, IAuthenticatedEncryptorConfiguration configuration, IServiceProvider services);
public IKey CreateNewKey(DateTimeOffset activationDate, DateTimeOffset expirationDate);
public IReadOnlyCollection<IKey> GetAllKeys();
public CancellationToken GetCacheExpirationToken();
public void RevokeAllKeys(DateTimeOffset revocationDate, string reason = null);
public void RevokeKey(Guid keyId, string reason = null);
}
•IAuthenticatedEncryptor Configuration 은 주로 새로운 Key 가 사용 하도록 규정 한 알고리즘 입 니 다.•IXmlRepository 는 키 가 어디 에 저장 되 는 지 를 제어 합 니 다.
IXmlRepository
IXmlRepository 인 터 페 이 스 는 주로 두 개의 API 만 제공 하면 지속 적 이 고 XML 을 검색 하 는 방법 을 제공 합 니 다.
•GetAllElements() : IReadOnlyCollection
•StoreElement(XElement element, string friendlyName)
저 희 는 IXmlRepository 인 터 페 이 스 를 실현 하 는 StoreElement 방법 을 통 해 data proctection xml 의 저장 위 치 를 정의 할 수 있 습 니 다.
GetAllElements 는 암호 화 된 xml 파일 을 검색 합 니 다.
인터페이스 부분 은 여기까지 쓰 세 요.이 편 은 제 가 아래 에 중점 을 두 고 싶 기 때문에 더 많은 인터페이스 소 개 는 공식 문서 로 보 세 요~
군집 장면
위의 API 는 약간 지루 해 보일 것 같 습 니 다.클 러 스 터 장면 에서 Data Protection 을 통 해 무엇 을 해 야 하 는 지 살 펴 보 겠 습 니 다.
제 가[상편]정리 에서 마지막 에 언급 한 것 처럼 분포 식 클 러 스 터 를 할 때 Data Protection 의 일부 체 제 는 우리 가 알 아야 합 니 다.이런 것들 을 모 르 면 당신 의 배치 에 번 거 로 움 을 줄 수 있 으 니 다음 에 보 겠 습 니 다.
클 러 스 터 를 만 들 때 우 리 는 ASP.NET Core Data Protection 에 관 한 세 가지 것 을 알 고 알 아야 한다.
1.프로그램 식별 자
"Application discriminator"는 응용 프로그램의 유일 성 을 표시 하 는 데 사용 된다.
이게 왜 필요 하지?클 러 스 터 환경 에서 구체 적 인 하드웨어 기기 환경 에 제한 을 받 지 않 으 면 기 계 를 운영 하 는 일부 차 이 를 제거 하려 면 특정한 표 지 를 추상 화하 여 응용 프로그램 자 체 를 표시 하고 이 표 지 를 사용 하여 서로 다른 응용 프로그램 을 구분 해 야 하기 때문이다.이 럴 때,우 리 는 응용 프로그램 Discriminator 를 지정 할 수 있 습 니 다.
services.AddDataProtection(DataProtection Options option)에서 applicationDiscriminator 는 매개 변수 로 전달 할 수 있 습 니 다.코드 를 보 세 요.
public void ConfigureServices(IServiceCollection services)
{
services.AddDataProtection();
services.AddDataProtection(DataProtectionOptions option);
}
//=========== :
public static class DataProtectionServiceCollectionExtensions
{
public static IDataProtectionBuilder AddDataProtection(this IServiceCollection services);
// ,
public static IDataProtectionBuilder AddDataProtection(this IServiceCollection services, Action<DataProtectionOptions> setupAction);
}
// DataProtectionOptions :
public class DataProtectionOptions
{
public string ApplicationDiscriminator { get; set; }
}
이 확장 자 는 IDataProtectionBuilder 로 되 돌아 가 는 것 을 볼 수 있 습 니 다.IDataProtectionBuilder 에는 SetApplicationName 이라는 확장 방법 이 있 습 니 다.이 확장 방법 은 내부 에 있 습 니까?아니면 수 정 된 ApplicationDiscriminator 의 값 입 니까?즉,다음 과 같은 표기 법 은 등가 라 고 할 수 있다.services.AddDataProtection(x => x.ApplicationDiscriminator = "my_app_sample_identity");
services.AddDataProtection().SetApplicationName("my_app_sample_identity");
즉,클 러 스 터 환경 에서 같은 프로그램 이 같은 값(ApplicationName or ApplicationDiscriminator)으로 설정 해 야 한 다 는 것 이다.
2.메 인 암호 화 키
"Master encryption key"는 클 라 이언 트 서버 가 요청 하 는 과정 에서 세 션 데이터,상태 등 을 암호 화 하 는 데 사 용 됩 니 다.인증 서 를 사용 하거나 windows DPAPI 나 레 지 스 트 등 설정 할 수 있 는 옵션 이 몇 개 있 습 니 다.윈도 우즈 플랫폼 이 아니면 레 지 스 트 와 윈도 DPAPI 를 사용 할 수 없다.
public void ConfigureServices(IServiceCollection services)
{
services.AddDataProtection()
//windows dpaip
.ProtectKeysWithDpapi()
// windows 8+ windows server2012+ ( Windows DPAPI-NG)
.ProtectKeysWithDpapiNG("SID={current account SID}", DpapiNGProtectionDescriptorFlags.None)
// windows 8+ windows server2012+ ( )
.ProtectKeysWithDpapiNG("CERTIFICATE=HashId:3BCE558E2AD3E0E34A7743EAB5AEA2A9BD2575A0", DpapiNGProtectionDescriptorFlags.None)
// , widnows ,linux 。
.ProtectKeysWithCertificate();
}
클 러 스 터 환경 에서 같은 메 인 암호 화 키 를 설정 해 야 합 니 다. 3.암호 화 후 저장 위치
[전편]에서 말 했 듯 이 기본적으로 Data Protection 은 xml 파일 을 생 성하 여 session 이나 상태의 키 파일 을 저장 합 니 다.이 파일 들 은 session 등 상태 데 이 터 를 암호 화하 거나 복호화 하 는 데 사 용 됩 니 다.
바로 전편 에서 말 한 그 비밀 키 저장 위치 입 니 다.
1.프로그램 이 Microsoft Azure 에 하 숙 되면'%HOME%\ASP.NET\\DataProtection-Keys'폴 더 에 저 장 됩 니 다.
2.프로그램 이 IIS 에 하 숙 되면 HKlm 레 지 스 트 의 ACLed 특수 레 지 스 트 키 에 저장 되 고 작업 프로 세 스 만 접근 할 수 있 으 며 windows 의 DPAPI 암호 화 를 사용 합 니 다.
3.현재 사용자 가 사용 할 수 있 는 win 10 또는 win 7 은'%LOCALAPPDATA%\ASP.NET\\DataProtection-Keys'폴 더 에 저 장 됩 니 다.똑 같이 사용 하 는 windows 의 DPAPI 암호 화 입 니 다.
4.이것 이 모두 부합 되 지 않 으 면 비밀 키 는 지속 되 지 않 습 니 다.즉,프로 세 스 가 닫 혔 을 때 생 성 된 비밀 키 를 잃 어 버 린 것 입 니 다.
클 러 스 터 환경 에서:
가장 쉬 운 방법 은 파일 공유,DPAPI 또는 레 지 스 트 리 지 를 통 해 암호 화 된 xml 파일 을 같은 곳 에 저장 하 는 것 이다.왜 가장 간단 합 니까?시스템 이 이미 봉인 되 어 있 기 때문에 불필요 한 코드 를 쓸 필요 가 없 지만 파일 공유 와 관련 된 포트 가 열 려 있 음 을 보증 해 야 합 니 다.다음 과 같다.
public void ConfigureServices(IServiceCollection services)
{
services.AddDataProtection()
//windows、Linux、macOS
.PersistKeysToFileSystem(new System.IO.DirectoryInfo("C:\\share_keys\\"))
//windows
.PersistKeysToRegistry(Microsoft.Win32.RegistryKey.FromHandle(null))
}
데이터베이스 나 Redis 등 저장 소 를 사용 하 는 등 확장 방법 을 스스로 정의 할 수도 있다. 그러나 일반적으로 Liux 에 배치 되면 확장 이 필요 합 니 다.다음은 우리 가 redis 로 저장 하고 싶 은 데 어떻게 해 야 하나 요?
어떻게 암호 화 키 집합의 저장 위 치 를 확장 합 니까?
우선,IXmlRepository 인터페이스 에 대한 redis 구현 클래스 RedisXmlRepository.cs 를 정의 합 니 다.
public class RedisXmlRepository : IXmlRepository, IDisposable
{
public static readonly string RedisHashKey = "DataProtectionXmlRepository";
private IConnectionMultiplexer _connection;
private bool _disposed = false;
public RedisXmlRepository(string connectionString, ILogger<RedisXmlRepository> logger)
: this(ConnectionMultiplexer.Connect(connectionString), logger)
{
}
public RedisXmlRepository(IConnectionMultiplexer connection, ILogger<RedisXmlRepository> logger)
{
if (connection == null)
{
throw new ArgumentNullException(nameof(connection));
}
if (logger == null)
{
throw new ArgumentNullException(nameof(logger));
}
this._connection = connection;
this.Logger = logger;
var configuration = Regex.Replace(this._connection.Configuration, @"password\s*=\s*[^,]*", "password=****", RegexOptions.IgnoreCase);
this.Logger.LogDebug("Storing data protection keys in Redis: {RedisConfiguration}", configuration);
}
public ILogger<RedisXmlRepository> Logger { get; private set; }
public void Dispose()
{
this.Dispose(true);
}
public IReadOnlyCollection<XElement> GetAllElements()
{
var database = this._connection.GetDatabase();
var hash = database.HashGetAll(RedisHashKey);
var elements = new List<XElement>();
if (hash == null || hash.Length == 0)
{
return elements.AsReadOnly();
}
foreach (var item in hash.ToStringDictionary())
{
elements.Add(XElement.Parse(item.Value));
}
this.Logger.LogDebug("Read {XmlElementCount} XML elements from Redis.", elements.Count);
return elements.AsReadOnly();
}
public void StoreElement(XElement element, string friendlyName)
{
if (element == null)
{
throw new ArgumentNullException(nameof(element));
}
if (string.IsNullOrEmpty(friendlyName))
{
friendlyName = Guid.NewGuid().ToString();
}
this.Logger.LogDebug("Storing XML element with friendly name {XmlElementFriendlyName}.", friendlyName);
this._connection.GetDatabase().HashSet(RedisHashKey, friendlyName, element.ToString());
}
protected virtual void Dispose(bool disposing)
{
if (!this._disposed)
{
if (disposing)
{
if (this._connection != null)
{
this._connection.Close();
this._connection.Dispose();
}
}
this._connection = null;
this._disposed = true;
}
}
}
그리고 임의의 확장 클래스 에서 확장 방법 을 정의 합 니 다.
public static IDataProtectionBuilder PersistKeysToRedis(this IDataProtectionBuilder builder, string redisConnectionString)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (redisConnectionString == null)
{
throw new ArgumentNullException(nameof(redisConnectionString));
}
if (redisConnectionString.Length == 0)
{
throw new ArgumentException("Redis connection string may not be empty.", nameof(redisConnectionString));
}
// services.AddDataProtection() , IXmlRepository,
// , ,
for (int i = builder.Services.Count - 1; i >= 0; i--)
{
if (builder.Services[i]?.ServiceType == descriptor.ServiceType)
{
builder.Services.RemoveAt(i);
}
}
var descriptor = ServiceDescriptor.Singleton<IXmlRepository>(services => new RedisXmlRepository(redisConnectionString, services.GetRequiredService<ILogger<RedisXmlRepository>>()))
builder.Services.Add(descriptor);
return builder.Use();
}
최종 Services 에서 DataProtection 에 관 한 것 은 다음 과 같 습 니 다.
public void ConfigureServices(IServiceCollection services)
{
services.AddDataProtection()
// ================ ==============
//
.SetApplicationName("my_app_sample_identity");
// ============= ===============
//windows dpaip
.ProtectKeysWithDpapi()
// windows 8+ windows server2012+ ( Windows DPAPI-NG)
.ProtectKeysWithDpapiNG("SID={current account SID}", DpapiNGProtectionDescriptorFlags.None)
// windows 8+ windows server2012+ ( )
.ProtectKeysWithDpapiNG("CERTIFICATE=HashId:3BCE558E2AD3E0E34A7743EAB5AEA2A9BD2575A0", DpapiNGProtectionDescriptorFlags.None)
// , widnows ,linux 。
.ProtectKeysWithCertificate();
// ============== =================
//windows、Linux、macOS
.PersistKeysToFileSystem(new System.IO.DirectoryInfo("C:\\share_keys\\"))
//windows
.PersistKeysToRegistry(Microsoft.Win32.RegistryKey.FromHandle(null))
// redis
.PersistKeysToRedis(Configuration.Section["RedisConnection"])
}
위의 설정 에서 사용 할 수 있 는 모든 설정 을 열 거 했 습 니 다.실제 항목 에 서 는 실제 상황 에 따라 선택해 야 합 니 다. 총결산
ASP.NET Core Data Protection 시 리 즈 를 드디어 다 썼 습 니 다.사실 이 부분 은 시간 이 많이 걸 렸 습 니 다.Data Protection 에 있어 저도 점진 적 인 학습 과정 이 므 로 일부 사람들 에 게 도움 이 되 었 으 면 합 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
.Net Core Excel 템플릿 읽기 Excel 파일 내보내기텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.