using System.Reflection; using System.Security.Cryptography; using System.Text.Json.Serialization; namespace DigitalData.Core.Security.Config { public class RSAFactoryParams : IJsonOnDeserialized { public int KeySizeInBits { get; init; } = 2048; public string PbePassword { internal get; init; } = Secrets.PBE_PASSWORD; public PbeEncryptionAlgorithm PbeEncryptionAlgorithm { get; init; } = PbeEncryptionAlgorithm.Aes256Cbc; public HashAlgorithmName PbeHashAlgorithm { get; init; } = HashAlgorithmName.SHA256; // TODO: add as json converter to IConfigurIConfiguration.Config public string PbeHashAlgorithmName { get => PbeHashAlgorithm.ToString(); init => PbeHashAlgorithm = (typeof(HashAlgorithmName).GetProperty(value, BindingFlags.Public | BindingFlags.Static)?.GetValue(null) is HashAlgorithmName hashAlgorithmName) ? hashAlgorithmName : new(value); } public int PbeIterationCount { get; init; } = 100_000; public string EncryptedPrivateKeyPemLabel { get; init; } = "ENCRYPTED PRIVATE KEY"; private PbeParameters? _pbeParameters; [JsonIgnore] public PbeParameters PbeParameters => _pbeParameters!; /// /// Provides a thread-safe initialization mechanism using Lazy initialization. /// private readonly Lazy _lazyInitializer; public bool IsInitialized => _lazyInitializer.IsValueCreated; public RSAFactoryParams() { _lazyInitializer = new(() => { AfterCreate?.Invoke(); return true; }); AfterCreate += () => _pbeParameters = new PbeParameters(PbeEncryptionAlgorithm, PbeHashAlgorithm, PbeIterationCount); } protected event Action AfterCreate; public void Init() => _ = _lazyInitializer.Value; public void OnDeserialized() => Init(); } }