5 Commits

Author SHA1 Message Date
Developer 02
683b95c205 refactor(RSAExtensions): GetRSADecryptor, TryGetRSADecryptor, GetRSAEncryptor und TryGetRSADecryptor Methoden hinzugefügt. 2024-11-20 00:15:27 +01:00
Developer 02
f28b43cc06 refactor(RSADecryptor): Lazy Loading in Encryptor Getter integriert, um die Leistung zu verbessern. 2024-11-19 23:58:04 +01:00
Developer 02
777a8a73ac refactor: AddSecurity-Methode aktualisiert, um ICryptFactory direkt mit der CryptFactory-Instanz zu registrieren 2024-11-19 23:51:49 +01:00
Developer 02
77fc06991b feat(CryptFactory): Erstellung einer separaten RSAFactory zur Erzeugung einer statischen Instanz 2024-11-19 23:49:34 +01:00
Developer 02
eeb50e837d feat: Unterstützung für IRSADecryptor und Verwaltung der RSA-Entschlüsselung in den Klassen ICryptFactory und CryptFactory hinzugefügt
ICryptFactory:
- `IRSADecryptor this[string key]`-Indexer für den Zugriff auf Entschlüssler per Schlüssel hinzugefügt.
- Methode `TryGetRSADecryptor` für das sichere Abrufen von Entschlüsslern eingeführt.

CryptFactory:
- `IRSADecryptor`-Indexer für die Verwaltung von Entschlüsslern implementiert.
- Ein `Decryptors`-Dictionary hinzugefügt, um RSA-Entschlüssler nach Schlüssel zu speichern.
- Konstruktor aktualisiert, um `Decryptors` mit einem bereitgestellten oder leeren Dictionary zu initialisieren.
- `TryGetRSADecryptor` zur Entschlüssler-Abfrage implementiert.
2024-11-19 23:14:44 +01:00
6 changed files with 111 additions and 68 deletions

View File

@@ -4,19 +4,19 @@ namespace DigitalData.Core.Abstractions.Security
{
public interface ICryptFactory
{
public int KeySizeInBits { get; init; }
int KeySizeInBits { get; init; }
public string PbePassword { init; }
string PbePassword { init; }
public PbeEncryptionAlgorithm PbeEncryptionAlgorithm { get; init; }
PbeEncryptionAlgorithm PbeEncryptionAlgorithm { get; init; }
public HashAlgorithmName PbeHashAlgorithmName { get; init; }
HashAlgorithmName PbeHashAlgorithmName { get; init; }
public int PbeIterationCount { get; init; }
int PbeIterationCount { get; init; }
public PbeParameters PbeParameters { get; }
PbeParameters PbeParameters { get; }
public string EncryptedPrivateKeyPemLabel { get; init; }
string EncryptedPrivateKeyPemLabel { get; init; }
string CreateRSAPrivateKeyPem(int? keySizeInBits = null);
@@ -26,5 +26,9 @@ namespace DigitalData.Core.Abstractions.Security
PbeEncryptionAlgorithm? pbeEncryptionAlgorithm = null,
HashAlgorithmName? hashAlgorithmName = null,
int? iterationCount = null);
IRSADecryptor this[string key] { get; }
bool TryGetRSADecryptor(string key, out IRSADecryptor? decryptor);
}
}

View File

@@ -17,5 +17,28 @@ namespace DigitalData.Core.Security.Extensions
public static IRSAEncryptor? GetEncryptor(this IDictionary<string, IRSAEncryptor> pairs, string issuer, string audience)
=> pairs.TryGetEncryptor(issuer: issuer, audience: audience, out var encryptor) ? encryptor : null;
public static IRSADecryptor GetRSADecryptor(this ICryptFactory factory, string issuer, string audience)
=> factory[$"{issuer}:{audience}"];
public static bool TryGetRSADecryptor(this ICryptFactory factory, string issuer, string audience, out IRSADecryptor? decryptor)
=> factory.TryGetRSADecryptor($"{issuer}:{audience}", out decryptor);
public static IRSAEncryptor GetRSAEncryptor(this ICryptFactory factory, string issuer, string audience)
=> factory[$"{issuer}:{audience}"].Encryptor;
public static bool TryGetRSADecryptor(this ICryptFactory factory, string issuer, string audience, out IRSAEncryptor? encryptor)
{
if(factory.TryGetRSADecryptor($"{issuer}:{audience}", out var decryptor) && decryptor is not null)
{
encryptor = decryptor.Encryptor;
return true;
}
else
{
encryptor = null;
return false;
}
}
}
}

View File

@@ -1,62 +1,21 @@
using DigitalData.Core.Abstractions.Security;
using Microsoft.Extensions.Logging;
using System.Security.Cryptography;
namespace DigitalData.Core.Security
{
public class CryptFactory : ICryptFactory
public class CryptFactory : RSAFactory, ICryptFactory
{
private static readonly Lazy<CryptFactory> LazyInstance = new (() => new ());
private readonly IDictionary<string, IRSADecryptor> _decryptors;
public static CryptFactory Instance => LazyInstance.Value;
public IRSADecryptor this[string key] { get => _decryptors[key]; set => _decryptors[key] = value; }
public int KeySizeInBits { get; init; } = 2048;
public string PbePassword { private get; init; } = Secrets.PBE_PASSWORD;
public PbeEncryptionAlgorithm PbeEncryptionAlgorithm { get; init; } = PbeEncryptionAlgorithm.Aes256Cbc;
public HashAlgorithmName PbeHashAlgorithmName { get; init; } = HashAlgorithmName.SHA256;
public int PbeIterationCount { get; init; } = 100_000;
private readonly Lazy<PbeParameters> _lazyPbeParameters;
public PbeParameters PbeParameters => _lazyPbeParameters.Value;
public string EncryptedPrivateKeyPemLabel { get; init; } = "ENCRYPTED PRIVATE KEY";
public CryptFactory(ILogger<CryptFactory>? logger = null)
public CryptFactory(ILogger<CryptFactory> logger, IDictionary<string, IRSADecryptor> decryptors) : base()
{
_lazyPbeParameters = new(() => new PbeParameters(PbeEncryptionAlgorithm, PbeHashAlgorithmName, PbeIterationCount));
_decryptors = decryptors ?? new Dictionary<string, IRSADecryptor>();
logger?.LogInformation("CryptFactory initialized. Core.Secrets version: {Version}, Created on: {CreationDate}.", Secrets.Version, Secrets.CreationDate.ToString("dd.MM.yyyy"));
logger?.LogInformation("Core.Secrets version: {Version}, Created on: {CreationDate}.", Secrets.Version, Secrets.CreationDate.ToString("dd.MM.yyyy"));
}
public string CreateRSAPrivateKeyPem(int? keySizeInBits = null)
=> RSA.Create(keySizeInBits ?? KeySizeInBits).ExportRSAPrivateKeyPem();
public string CreateEncryptedPrivateKeyPem(
int? keySizeInBits = null,
string? password = null,
PbeEncryptionAlgorithm? pbeEncryptionAlgorithm = null,
HashAlgorithmName? hashAlgorithmName = null,
int? iterationCount = null)
{
password ??= PbePassword;
var pbeParameters = (pbeEncryptionAlgorithm is null && hashAlgorithmName is null && iterationCount is null)
? new PbeParameters(
pbeEncryptionAlgorithm ?? PbeEncryptionAlgorithm,
hashAlgorithmName ?? PbeHashAlgorithmName,
iterationCount ?? PbeIterationCount)
: PbeParameters;
var encryptedPrivateKey = RSA.Create(keySizeInBits ?? KeySizeInBits).ExportEncryptedPkcs8PrivateKey(password.AsSpan(), pbeParameters);
var pemChars = PemEncoding.Write(EncryptedPrivateKeyPemLabel, encryptedPrivateKey);
return new string(pemChars);
}
public bool TryGetRSADecryptor(string key, out IRSADecryptor? decryptor) => _decryptors.TryGetValue(key, out decryptor);
}
}

View File

@@ -8,7 +8,7 @@ namespace DigitalData.Core.Security
{
public static IServiceCollection AddSecurity(this IServiceCollection services)
{
services.TryAddScoped<ICryptFactory>(_ => CryptFactory.Instance);
services.TryAddScoped<ICryptFactory, CryptFactory>();
return services;
}

View File

@@ -10,19 +10,18 @@ namespace DigitalData.Core.Security
public bool IsEncrypted => Password is not null;
public IRSAEncryptor Encryptor
{
get
{
return new RSAEncryptor()
{
Pem = _rsa.ExportRSAPublicKeyPem(),
Padding = Padding
};
}
}
private readonly Lazy<IRSAEncryptor> _lazyEncryptor;
internal RSADecryptor() { }
public IRSAEncryptor Encryptor => _lazyEncryptor.Value;
internal RSADecryptor()
{
_lazyEncryptor = new(() => new RSAEncryptor()
{
Pem = _rsa.ExportRSAPublicKeyPem(),
Padding = Padding
});
}
[OnDeserialized]
private void OnDeserialized(StreamingContext context) => Init();

View File

@@ -0,0 +1,58 @@
using System.Security.Cryptography;
namespace DigitalData.Core.Security
{
public class RSAFactory
{
private static readonly Lazy<RSAFactory> LazyInstance = new(() => new());
public static RSAFactory Static => LazyInstance.Value;
public int KeySizeInBits { get; init; } = 2048;
public string PbePassword { private get; init; } = Secrets.PBE_PASSWORD;
public PbeEncryptionAlgorithm PbeEncryptionAlgorithm { get; init; } = PbeEncryptionAlgorithm.Aes256Cbc;
public HashAlgorithmName PbeHashAlgorithmName { get; init; } = HashAlgorithmName.SHA256;
public int PbeIterationCount { get; init; } = 100_000;
private readonly Lazy<PbeParameters> _lazyPbeParameters;
public PbeParameters PbeParameters => _lazyPbeParameters.Value;
public string EncryptedPrivateKeyPemLabel { get; init; } = "ENCRYPTED PRIVATE KEY";
internal RSAFactory()
{
_lazyPbeParameters = new(() => new PbeParameters(PbeEncryptionAlgorithm, PbeHashAlgorithmName, PbeIterationCount));
}
public string CreateRSAPrivateKeyPem(int? keySizeInBits = null)
=> RSA.Create(keySizeInBits ?? KeySizeInBits).ExportRSAPrivateKeyPem();
public string CreateEncryptedPrivateKeyPem(
int? keySizeInBits = null,
string? password = null,
PbeEncryptionAlgorithm? pbeEncryptionAlgorithm = null,
HashAlgorithmName? hashAlgorithmName = null,
int? iterationCount = null)
{
password ??= PbePassword;
var pbeParameters = (pbeEncryptionAlgorithm is null && hashAlgorithmName is null && iterationCount is null)
? new PbeParameters(
pbeEncryptionAlgorithm ?? PbeEncryptionAlgorithm,
hashAlgorithmName ?? PbeHashAlgorithmName,
iterationCount ?? PbeIterationCount)
: PbeParameters;
var encryptedPrivateKey = RSA.Create(keySizeInBits ?? KeySizeInBits).ExportEncryptedPkcs8PrivateKey(password.AsSpan(), pbeParameters);
var pemChars = PemEncoding.Write(EncryptedPrivateKeyPemLabel, encryptedPrivateKey);
return new string(pemChars);
}
}
}