using System.Security.Cryptography; using System.Text; using Microsoft.JSInterop; using System.Text.Json; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; namespace Front.Program.Services; public class SecureService { private readonly ILogger _logger; private readonly IJSRuntime _jsRuntime; private readonly IWebAssemblyHostEnvironment _environment; private string? _key; private string? _iv; private Task? _initializationTask; public SecureService( ILogger logger, IJSRuntime jsRuntime, IWebAssemblyHostEnvironment environment) { _logger = logger; _jsRuntime = jsRuntime; _environment = environment; _initializationTask = InitializeAsync(); } private async Task InitializeAsync() { try { var configFile = $"appsettings.{_environment.Environment}.json"; _logger.LogInformation($"설정 파일 로드: {configFile}"); var config = await _jsRuntime.InvokeAsync("loadConfig", configFile); if (config.ValueKind == JsonValueKind.Null) { throw new InvalidOperationException($"설정 파일을 로드할 수 없습니다: {configFile}"); } var security = config.GetProperty("Security"); _key = security.GetProperty("EncryptionKey").GetString() ?? throw new ArgumentNullException("Security:EncryptionKey"); _iv = security.GetProperty("EncryptionIV").GetString() ?? throw new ArgumentNullException("Security:EncryptionIV"); } catch (Exception ex) { _logger.LogError($"설정 로드 중 오류 발생: {ex.Message}"); throw; } } private async Task EnsureInitializedAsync() { if (_initializationTask != null) { await _initializationTask; _initializationTask = null; } } private byte[] GetKeyBytes(string key) { using (var sha256 = SHA256.Create()) { return sha256.ComputeHash(Encoding.UTF8.GetBytes(key)); } } private byte[] GetIVBytes(string iv) { using (var sha256 = SHA256.Create()) { var hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(iv)); return hash.Take(16).ToArray(); // IV는 16바이트만 필요 } } public async Task EncryptAsync(string plainText) { await EnsureInitializedAsync(); if (_key == null || _iv == null) throw new InvalidOperationException("암호화 키가 초기화되지 않았습니다."); try { return await _jsRuntime.InvokeAsync("encryptText", plainText, _key, _iv); } catch (Exception ex) { _logger.LogError($"암호화 중 오류 발생: {ex.Message}"); throw; } } public async Task DecryptAsync(string cipherText) { await EnsureInitializedAsync(); if (_key == null || _iv == null) throw new InvalidOperationException("암호화 키가 초기화되지 않았습니다."); try { return await _jsRuntime.InvokeAsync("decryptText", cipherText, _key, _iv); } catch (Exception ex) { _logger.LogError($"복호화 중 오류 발생: {ex.Message}"); throw; } } // 동기 메서드는 비동기 메서드를 호출하도록 수정 public string Encrypt(string plainText) => EncryptAsync(plainText).GetAwaiter().GetResult(); public string Decrypt(string cipherText) => DecryptAsync(cipherText).GetAwaiter().GetResult(); }