| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647 |
- namespace Application.Abstractions.Crypto;
- /// <summary>
- /// Config 문자열 컬럼에 키 버전을 함께 담아 암호화 저장하는 헬퍼.
- /// 별도 KeyVersion 컬럼이 없는 Config 특성상 "enc:v{version}:{Base64}" 자체 포맷을 사용한다.
- /// 접두사가 없는 값은 레거시 평문으로 간주해 그대로 반환한다 (하위호환).
- /// </summary>
- public static class EncryptedConfigValue
- {
- private const string Prefix = "enc:v";
- /// <summary>평문을 현재 키 버전으로 암호화해 버전 접두사 포맷으로 반환</summary>
- public static string Protect(IFieldEncryptor encryptor, string plaintext)
- {
- ArgumentNullException.ThrowIfNull(encryptor);
- return $"{Prefix}{encryptor.CurrentKeyVersion}:{encryptor.Encrypt(plaintext)}";
- }
- /// <summary>버전 접두사 포맷 여부</summary>
- public static bool IsProtected(string? value)
- {
- return value is not null && value.StartsWith(Prefix, StringComparison.Ordinal);
- }
- /// <summary>버전 접두사 포맷이면 복호화, 아니면(레거시 평문) 그대로 반환</summary>
- public static string Unprotect(IFieldEncryptor encryptor, string value)
- {
- ArgumentNullException.ThrowIfNull(encryptor);
- ArgumentNullException.ThrowIfNull(value);
- if (!IsProtected(value))
- {
- return value;
- }
- var rest = value.AsSpan(Prefix.Length);
- var separator = rest.IndexOf(':');
- if (separator <= 0 || !int.TryParse(rest[..separator], out var version))
- {
- throw new InvalidOperationException("암호화된 설정 값의 키 버전 형식이 올바르지 않습니다.");
- }
- return encryptor.Decrypt(rest[(separator + 1)..].ToString(), version);
- }
- }
|