using DigitalData.Core.Abstractions.Security; using Microsoft.IdentityModel.Tokens; using System.Reflection; using System.Security.Cryptography; namespace DigitalData.Core.Security.Cryptographer { //TODO: Abstract RSA for future updates (using ECC, El Gamal or Lattice-based Cryptography) public class RSACryptographer : IRSACryptographer { public virtual string Pem { get; init; } public RSAEncryptionPadding Padding { get; init; } = RSAEncryptionPadding.OaepSHA256; // TODO: add as json converter to IConfigurIConfiguration.Config public string PaddingName { get => Padding.ToString(); init => Padding = typeof(RSAEncryptionPadding).GetProperty(value, BindingFlags.Public | BindingFlags.Static)?.GetValue(null) as RSAEncryptionPadding ?? throw new ArgumentException($"Padding '{value}' not found."); } protected virtual RSA RSA { get; } = RSA.Create(); public string Issuer { get; init; } = string.Empty; public string Audience { get; init; } = string.Empty; private readonly Lazy _lazyRsaSecurityKey; public RsaSecurityKey RsaSecurityKey => _lazyRsaSecurityKey.Value; #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. internal RSACryptographer() { _lazyRsaSecurityKey = new(() => new RsaSecurityKey(RSA)); } #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. } }