feat(RSAParams): Merged CryptoFactoryParams and RSAFactoryParams

This commit is contained in:
Developer 02
2025-03-14 11:14:18 +01:00
parent b8de148c52
commit 7dd8271f4a
7 changed files with 109 additions and 121 deletions

View File

@@ -1,49 +0,0 @@
using DigitalData.Core.Security.RSAKey.Auth;
using DigitalData.Core.Security.RSAKey.Crypto;
namespace DigitalData.Core.Security.Config
{
public class CryptoFactoryParams : RSAFactoryParams
{
public string PemDirectory { get; init; } = string.Empty;
/// <summary>
/// Represents the separator used to concatenate the components of a file-related token string.
/// </summary>
/// <remarks>
/// The resulting file-related token string is constructed as follows:
/// <c>string.Join(FileNameSeparator, Issuer, Audience, Secret_version)</c>.
/// If <c>Secret_version</c> is not null, it will be included in the concatenation.
/// </remarks>
/// <example>
/// For example, if <c>FileNameSeparator = "_-_"</c>, the output might look like:
/// <c>"Issuer_-_Audience_-_Secret_version"</c>.
/// </example>
public string FileNameSeparator { get; init; } = "_-_";
public string FileExtension { get; init; } = "pem";
/// <summary>
///This is the subtext of the pem file name. For the file to be automatically renewed, the name must be assigned to change periodically. For example, by default MM/2 will be refreshed every 2 months.
/// <br />
/// - <see cref="StringExtensions.ToTag(DateTime, string)" /> is used when converting to tag.
/// <br />
/// - If the format contains the symbol “//”, the method divides the numeric value obtained from the left side of the format
/// by one minus the numeric value obtained from the right side of the format string and adds one. For instance:
/// <br />
/// - If the date is 02.03.2024 and the format is "MM//2", it extracts the month (02), subtracts one (3), divides it by 2,
/// rounds down the outgoing number (1), adds one to the number (resulting in 2).
/// <br />
/// - If the format does not contain "//", the method uses the default <see cref="DateTime.ToString"/> format.
/// <br />
/// This method provides a way to format the date based on typical or customized rules, including mathematical operations like division.
/// </summary>
public string DateTagFormat { get; init; } = "MM//2";
public IEnumerable<RSADecryptor> Decryptors { get; init; } = new List<RSADecryptor>();
public IEnumerable<RSATokenDescriptor> TokenDescriptors { get; init; } = new List<RSATokenDescriptor>();
public RSADecryptor? VaultDecryptor { get; init; }
}
}

View File

@@ -1,57 +0,0 @@
using System.Reflection;
using System.Security.Cryptography;
using System.Text.Json.Serialization;
namespace DigitalData.Core.Security.Config
{
public class RSAFactoryParams
{
public int KeySizeInBits { get; init; } = Default.KeySizeInBits;
public string PbePassword { internal get; init; } = Default.PbePassword;
public PbeEncryptionAlgorithm PbeEncryptionAlgorithm { get; init; } = Default.PbeEncryptionAlgorithm;
public HashAlgorithmName PbeHashAlgorithm { get; init; } = Default.PbeHashAlgorithm;
// 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; } = Default.PbeIterationCount;
public string EncryptedPrivateKeyPemLabel { get; init; } = Default.EncryptedPrivateKeyPemLabel;
private readonly Lazy<PbeParameters> _lazyPbeParameters;
[JsonIgnore]
public PbeParameters PbeParameters => _lazyPbeParameters.Value;
public RSAFactoryParams()
{
_lazyPbeParameters = new(() => new PbeParameters(PbeEncryptionAlgorithm, PbeHashAlgorithm, PbeIterationCount));
}
public static class Default
{
public static readonly int KeySizeInBits = 2048;
public static readonly string PbePassword = Secrets.PBE_PASSWORD;
public static readonly PbeEncryptionAlgorithm PbeEncryptionAlgorithm = PbeEncryptionAlgorithm.Aes256Cbc;
public static readonly HashAlgorithmName PbeHashAlgorithm = HashAlgorithmName.SHA256;
public static readonly int PbeIterationCount = 100_000;
public static readonly string EncryptedPrivateKeyPemLabel = "ENCRYPTED PRIVATE KEY";
public static readonly PbeParameters PbeParameters = new(PbeEncryptionAlgorithm, PbeHashAlgorithm, PbeIterationCount);
}
}
}

View File

@@ -0,0 +1,94 @@
using DigitalData.Core.Security.RSAKey.Auth;
using DigitalData.Core.Security.RSAKey.Crypto;
using System.Reflection;
using System.Security.Cryptography;
namespace DigitalData.Core.Security.Config;
public class RSAParams
{
#region Factory Params
public int KeySizeInBits { get; init; } = Default.KeySizeInBits;
public string PbePassword { internal get; init; } = Default.PbePassword;
public PbeEncryptionAlgorithm PbeEncryptionAlgorithm { get; init; } = Default.PbeEncryptionAlgorithm;
public HashAlgorithmName PbeHashAlgorithm { get; init; } = Default.PbeHashAlgorithm;
// 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; } = Default.PbeIterationCount;
public string EncryptedPrivateKeyPemLabel { get; init; } = Default.EncryptedPrivateKeyPemLabel;
public PbeParameters PbeParameters => new(PbeEncryptionAlgorithm, PbeHashAlgorithm, PbeIterationCount);
public static class Default
{
public static readonly int KeySizeInBits = 2048;
public static readonly string PbePassword = Secrets.PBE_PASSWORD;
public static readonly PbeEncryptionAlgorithm PbeEncryptionAlgorithm = PbeEncryptionAlgorithm.Aes256Cbc;
public static readonly HashAlgorithmName PbeHashAlgorithm = HashAlgorithmName.SHA256;
public static readonly int PbeIterationCount = 100_000;
public static readonly string EncryptedPrivateKeyPemLabel = "ENCRYPTED PRIVATE KEY";
public static readonly PbeParameters PbeParameters = new(PbeEncryptionAlgorithm, PbeHashAlgorithm, PbeIterationCount);
}
#endregion
#region Pool Params
public string PemDirectory { get; init; } = string.Empty;
/// <summary>
/// Represents the separator used to concatenate the components of a file-related token string.
/// </summary>
/// <remarks>
/// The resulting file-related token string is constructed as follows:
/// <c>string.Join(FileNameSeparator, Issuer, Audience, Secret_version)</c>.
/// If <c>Secret_version</c> is not null, it will be included in the concatenation.
/// </remarks>
/// <example>
/// For example, if <c>FileNameSeparator = "_-_"</c>, the output might look like:
/// <c>"Issuer_-_Audience_-_Secret_version"</c>.
/// </example>
public string FileNameSeparator { get; init; } = "_-_";
public string FileExtension { get; init; } = "pem";
/// <summary>
///This is the subtext of the pem file name. For the file to be automatically renewed, the name must be assigned to change periodically. For example, by default MM/2 will be refreshed every 2 months.
/// <br />
/// - <see cref="StringExtensions.ToTag(DateTime, string)" /> is used when converting to tag.
/// <br />
/// - If the format contains the symbol “//”, the method divides the numeric value obtained from the left side of the format
/// by one minus the numeric value obtained from the right side of the format string and adds one. For instance:
/// <br />
/// - If the date is 02.03.2024 and the format is "MM//2", it extracts the month (02), subtracts one (3), divides it by 2,
/// rounds down the outgoing number (1), adds one to the number (resulting in 2).
/// <br />
/// - If the format does not contain "//", the method uses the default <see cref="DateTime.ToString"/> format.
/// <br />
/// This method provides a way to format the date based on typical or customized rules, including mathematical operations like division.
/// </summary>
public string DateTagFormat { get; init; } = "MM//2";
public IEnumerable<RSADecryptor> Decryptors { get; init; } = new List<RSADecryptor>();
public IEnumerable<RSATokenDescriptor> TokenDescriptors { get; init; } = new List<RSATokenDescriptor>();
public RSADecryptor? VaultDecryptor { get; init; }
#endregion
}

View File

@@ -17,7 +17,7 @@ namespace DigitalData.Core.Security
/// <param name="section"></param>
/// <returns>The updated <see cref="IServiceCollection"/> with the RSA Factory registered.</returns>
public static IServiceCollection AddCryptoFactory(this IServiceCollection services, IConfiguration configuration) => services
.Configure<CryptoFactoryParams>(configuration)
.Configure<RSAParams>(configuration)
.AddAutoMapper(typeof(MappingProfile).Assembly)
.AddSingleton<IAsymmetricKeyPool, RSAPool>()
.AddSingleton<IAsymmetricKeyFactory, RSAFactory>()

View File

@@ -9,11 +9,11 @@ namespace DigitalData.Core.Security.Services;
public class PemFileInitalizer : BackgroundService
{
private readonly CryptoFactoryParams _factoryParams;
private readonly RSAParams _factoryParams;
private readonly ILogger<PemFileInitalizer> _logger;
public PemFileInitalizer(IOptions<CryptoFactoryParams> factoryParamsOptions, ILogger<PemFileInitalizer> logger)
public PemFileInitalizer(IOptions<RSAParams> factoryParamsOptions, ILogger<PemFileInitalizer> logger)
{
_factoryParams = factoryParamsOptions.Value;
_logger = logger;

View File

@@ -11,7 +11,7 @@ public class RSAFactory : IAsymmetricKeyFactory
public string CreatePrivateKeyPem(int? keySizeInBits = null, bool encrypt = false) => encrypt
? CreateEncryptedPrivateKeyPem(keySizeInBits: keySizeInBits)
: RSA.Create(keySizeInBits ?? RSAFactoryParams.Default.KeySizeInBits).ExportRSAPrivateKeyPem();
: RSA.Create(keySizeInBits ?? RSAParams.Default.KeySizeInBits).ExportRSAPrivateKeyPem();
public string CreateEncryptedPrivateKeyPem(
PbeEncryptionAlgorithm? pbeEncryptionAlgorithm = null,
@@ -20,16 +20,16 @@ public class RSAFactory : IAsymmetricKeyFactory
int? keySizeInBits = null,
string? password = null)
{
password ??= RSAFactoryParams.Default.PbePassword;
password ??= RSAParams.Default.PbePassword;
var pbeParameters = new PbeParameters(
pbeEncryptionAlgorithm ?? RSAFactoryParams.Default.PbeEncryptionAlgorithm,
hashAlgorithmName ?? RSAFactoryParams.Default.PbeHashAlgorithm,
iterationCount ?? RSAFactoryParams.Default.PbeIterationCount);
pbeEncryptionAlgorithm ?? RSAParams.Default.PbeEncryptionAlgorithm,
hashAlgorithmName ?? RSAParams.Default.PbeHashAlgorithm,
iterationCount ?? RSAParams.Default.PbeIterationCount);
var encryptedPrivateKey = RSA.Create(keySizeInBits ?? RSAFactoryParams.Default.KeySizeInBits).ExportEncryptedPkcs8PrivateKey(password.AsSpan(), pbeParameters);
var encryptedPrivateKey = RSA.Create(keySizeInBits ?? RSAParams.Default.KeySizeInBits).ExportEncryptedPkcs8PrivateKey(password.AsSpan(), pbeParameters);
var pemChars = PemEncoding.Write(RSAFactoryParams.Default.EncryptedPrivateKeyPemLabel, encryptedPrivateKey);
var pemChars = PemEncoding.Write(RSAParams.Default.EncryptedPrivateKeyPemLabel, encryptedPrivateKey);
return new string(pemChars);
}
@@ -39,11 +39,11 @@ public class RSAFactory : IAsymmetricKeyFactory
int? keySizeInBits = null,
string? password = null)
{
password ??= RSAFactoryParams.Default.PbePassword;
password ??= RSAParams.Default.PbePassword;
var encryptedPrivateKey = RSA.Create(keySizeInBits ?? RSAFactoryParams.Default.KeySizeInBits).ExportEncryptedPkcs8PrivateKey(password.AsSpan(), pbeParameters);
var encryptedPrivateKey = RSA.Create(keySizeInBits ?? RSAParams.Default.KeySizeInBits).ExportEncryptedPkcs8PrivateKey(password.AsSpan(), pbeParameters);
var pemChars = PemEncoding.Write(RSAFactoryParams.Default.EncryptedPrivateKeyPemLabel, encryptedPrivateKey);
var pemChars = PemEncoding.Write(RSAParams.Default.EncryptedPrivateKeyPemLabel, encryptedPrivateKey);
return new string(pemChars);
}

View File

@@ -7,7 +7,7 @@ namespace DigitalData.Core.Security.Services;
public class RSAPool : RSAFactory, IAsymmetricKeyPool, IAsymmetricKeyFactory
{
private readonly CryptoFactoryParams _params;
private readonly RSAParams _params;
public IEnumerable<IAsymmetricDecryptor> Decryptors { get; }
@@ -18,7 +18,7 @@ public class RSAPool : RSAFactory, IAsymmetricKeyPool, IAsymmetricKeyFactory
public IEnumerable<IAsymmetricTokenDescriptor> TokenDescriptors { get; init; } = new List<IAsymmetricTokenDescriptor>();
public RSAPool(IOptions<CryptoFactoryParams> cryptoFactoryParamsOptions, ILogger<RSAPool>? logger = null)
public RSAPool(IOptions<RSAParams> cryptoFactoryParamsOptions, ILogger<RSAPool>? logger = null)
{
_params = cryptoFactoryParamsOptions.Value;