From a4b96c2f3e956bb97503078acdd3d3a375594ee8 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Mon, 2 Dec 2024 13:46:15 +0100 Subject: [PATCH 01/61] feat(Sicherheit): Umbenennung von CryptFactory und seiner Schnittstelle in (I)AsymCryptService --- .../Security/{ICryptFactory.cs => IAsymCryptService.cs} | 2 +- DigitalData.Core.Security.Extensions/RSAExtensions.cs | 4 ++-- .../{CryptFactory.cs => AsymCryptService.cs} | 4 ++-- DigitalData.Core.Security/DIExtensions.cs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) rename DigitalData.Core.Abstractions/Security/{ICryptFactory.cs => IAsymCryptService.cs} (98%) rename DigitalData.Core.Security/{CryptFactory.cs => AsymCryptService.cs} (76%) diff --git a/DigitalData.Core.Abstractions/Security/ICryptFactory.cs b/DigitalData.Core.Abstractions/Security/IAsymCryptService.cs similarity index 98% rename from DigitalData.Core.Abstractions/Security/ICryptFactory.cs rename to DigitalData.Core.Abstractions/Security/IAsymCryptService.cs index 94c3109..e4bfc5a 100644 --- a/DigitalData.Core.Abstractions/Security/ICryptFactory.cs +++ b/DigitalData.Core.Abstractions/Security/IAsymCryptService.cs @@ -2,7 +2,7 @@ namespace DigitalData.Core.Abstractions.Security { - public interface ICryptFactory + public interface IAsymCryptService { int KeySizeInBits { get; init; } diff --git a/DigitalData.Core.Security.Extensions/RSAExtensions.cs b/DigitalData.Core.Security.Extensions/RSAExtensions.cs index 0599cfa..be2ef74 100644 --- a/DigitalData.Core.Security.Extensions/RSAExtensions.cs +++ b/DigitalData.Core.Security.Extensions/RSAExtensions.cs @@ -13,10 +13,10 @@ namespace DigitalData.Core.Security.Extensions return rsa; } - public static IRSADecryptor GetRSADecryptor(this ICryptFactory factory, string issuer, string audience, Version? version = null, string? seperator = null) + public static IRSADecryptor GetRSADecryptor(this IAsymCryptService factory, string issuer, string audience, Version? version = null, string? seperator = null) => factory[factory.RSAKeyNameFormatter(issuer, audience, true, version, seperator)]; - public static bool TryGetRSADecryptor(this ICryptFactory factory, string issuer, string audience, out IRSADecryptor? decryptor, Version? version = null, string? seperator = null) + public static bool TryGetRSADecryptor(this IAsymCryptService factory, string issuer, string audience, out IRSADecryptor? decryptor, Version? version = null, string? seperator = null) => factory.TryGetRSADecryptor(factory.RSAKeyNameFormatter(issuer, audience, true, version, seperator), out decryptor); private static string CreatePath(string filename, string? directory = null) diff --git a/DigitalData.Core.Security/CryptFactory.cs b/DigitalData.Core.Security/AsymCryptService.cs similarity index 76% rename from DigitalData.Core.Security/CryptFactory.cs rename to DigitalData.Core.Security/AsymCryptService.cs index 0549cd2..c2bc1ea 100644 --- a/DigitalData.Core.Security/CryptFactory.cs +++ b/DigitalData.Core.Security/AsymCryptService.cs @@ -3,7 +3,7 @@ using Microsoft.Extensions.Logging; namespace DigitalData.Core.Security { - public class CryptFactory : RSAFactory, ICryptFactory + public class AsymCryptService : RSAFactory, IAsymCryptService { private readonly IDictionary _decryptors; @@ -11,7 +11,7 @@ namespace DigitalData.Core.Security public Func RSAKeyNameFormatter { get; } - public CryptFactory(ILogger logger, IDictionary decryptors, Func rsaKeyNameFormatter) : base() + public AsymCryptService(ILogger logger, IDictionary decryptors, Func rsaKeyNameFormatter) : base() { _decryptors = decryptors ?? new Dictionary(); diff --git a/DigitalData.Core.Security/DIExtensions.cs b/DigitalData.Core.Security/DIExtensions.cs index 699f1c6..012ff26 100644 --- a/DigitalData.Core.Security/DIExtensions.cs +++ b/DigitalData.Core.Security/DIExtensions.cs @@ -8,7 +8,7 @@ namespace DigitalData.Core.Security { public static IServiceCollection AddSecurity(this IServiceCollection services) { - services.TryAddScoped(); + services.TryAddScoped(); return services; } From f720ea9cd611c5d9629afefac7fb2a906773e66e Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Mon, 2 Dec 2024 15:10:51 +0100 Subject: [PATCH 02/61] =?UTF-8?q?refactor(IRSAFactory):=20Erstellt,=20um?= =?UTF-8?q?=20die=20Funktionalit=C3=A4t=20von=20RSAFactory=20zu=20trennen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Security/IAsymCryptService.cs | 29 ++--------------- .../Security/IRSAFactory.cs | 32 +++++++++++++++++++ DigitalData.Core.Security/AsymCryptService.cs | 4 +-- DigitalData.Core.Security/DIExtensions.cs | 1 + DigitalData.Core.Security/RSAFactory.cs | 2 +- 5 files changed, 38 insertions(+), 30 deletions(-) create mode 100644 DigitalData.Core.Abstractions/Security/IRSAFactory.cs diff --git a/DigitalData.Core.Abstractions/Security/IAsymCryptService.cs b/DigitalData.Core.Abstractions/Security/IAsymCryptService.cs index e4bfc5a..ef8ecbc 100644 --- a/DigitalData.Core.Abstractions/Security/IAsymCryptService.cs +++ b/DigitalData.Core.Abstractions/Security/IAsymCryptService.cs @@ -1,23 +1,7 @@ -using System.Security.Cryptography; - -namespace DigitalData.Core.Abstractions.Security +namespace DigitalData.Core.Abstractions.Security { - public interface IAsymCryptService + public interface IAsymCryptService : IRSAFactory { - int KeySizeInBits { get; init; } - - string PbePassword { init; } - - PbeEncryptionAlgorithm PbeEncryptionAlgorithm { get; init; } - - HashAlgorithmName PbeHashAlgorithmName { get; init; } - - int PbeIterationCount { get; init; } - - PbeParameters PbeParameters { get; } - - string EncryptedPrivateKeyPemLabel { get; init; } - /// /// Gets the formatter function for generating RSA key names. /// This formatter takes an issuer, audience, isPrivate, and optional version and separator @@ -31,15 +15,6 @@ namespace DigitalData.Core.Abstractions.Security /// A formatted string combining the issuer, audience, and separator, which adheres to valid file naming rules. /// Thrown when the issuer, audience, or separator contains invalid characters or when the separator is present within the issuer or audience. Func RSAKeyNameFormatter { get; } - - string CreateRSAPrivateKeyPem(int? keySizeInBits = null); - - string CreateEncryptedPrivateKeyPem( - int? keySizeInBits = null, - string? password = null, - PbeEncryptionAlgorithm? pbeEncryptionAlgorithm = null, - HashAlgorithmName? hashAlgorithmName = null, - int? iterationCount = null); IRSADecryptor this[string key] { get; } diff --git a/DigitalData.Core.Abstractions/Security/IRSAFactory.cs b/DigitalData.Core.Abstractions/Security/IRSAFactory.cs new file mode 100644 index 0000000..6293b66 --- /dev/null +++ b/DigitalData.Core.Abstractions/Security/IRSAFactory.cs @@ -0,0 +1,32 @@ +using System.Security.Cryptography; + +namespace DigitalData.Core.Abstractions.Security +{ + public interface IRSAFactory + { + int KeySizeInBits { get; init; } + + string PbePassword { init; } + + PbeEncryptionAlgorithm PbeEncryptionAlgorithm { get; init; } + + HashAlgorithmName PbeHashAlgorithmName { get; init; } + + int PbeIterationCount { get; init; } + + PbeParameters PbeParameters { get; } + + string EncryptedPrivateKeyPemLabel { get; init; } + + string CreateRSAPrivateKeyPem(int? keySizeInBits = null); + + string CreateEncryptedPrivateKeyPem( + int? keySizeInBits = null, + string? password = null, + PbeEncryptionAlgorithm? pbeEncryptionAlgorithm = null, + HashAlgorithmName? hashAlgorithmName = null, + int? iterationCount = null); + + Task ReadRSADecryptorAsync(string path, Version? version = null, CancellationToken cancellationToken = default); + } +} \ No newline at end of file diff --git a/DigitalData.Core.Security/AsymCryptService.cs b/DigitalData.Core.Security/AsymCryptService.cs index c2bc1ea..2b867a4 100644 --- a/DigitalData.Core.Security/AsymCryptService.cs +++ b/DigitalData.Core.Security/AsymCryptService.cs @@ -3,7 +3,7 @@ using Microsoft.Extensions.Logging; namespace DigitalData.Core.Security { - public class AsymCryptService : RSAFactory, IAsymCryptService + public class AsymCryptService : RSAFactory, IAsymCryptService, IRSAFactory { private readonly IDictionary _decryptors; @@ -11,7 +11,7 @@ namespace DigitalData.Core.Security public Func RSAKeyNameFormatter { get; } - public AsymCryptService(ILogger logger, IDictionary decryptors, Func rsaKeyNameFormatter) : base() + public AsymCryptService(IDictionary decryptors, Func rsaKeyNameFormatter, ILogger? logger = null) : base() { _decryptors = decryptors ?? new Dictionary(); diff --git a/DigitalData.Core.Security/DIExtensions.cs b/DigitalData.Core.Security/DIExtensions.cs index 012ff26..28f4596 100644 --- a/DigitalData.Core.Security/DIExtensions.cs +++ b/DigitalData.Core.Security/DIExtensions.cs @@ -8,6 +8,7 @@ namespace DigitalData.Core.Security { public static IServiceCollection AddSecurity(this IServiceCollection services) { + services.TryAddScoped(sp => RSAFactory.Static); services.TryAddScoped(); return services; diff --git a/DigitalData.Core.Security/RSAFactory.cs b/DigitalData.Core.Security/RSAFactory.cs index 9425dbb..846f3a5 100644 --- a/DigitalData.Core.Security/RSAFactory.cs +++ b/DigitalData.Core.Security/RSAFactory.cs @@ -4,7 +4,7 @@ using System.Text; namespace DigitalData.Core.Security { - public class RSAFactory + public class RSAFactory : IRSAFactory { private static readonly Lazy LazyInstance = new(() => new()); From 5991444efdcf57cef599041c2a6dd90283daa498 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Mon, 2 Dec 2024 18:08:13 +0100 Subject: [PATCH 03/61] feat(RSAFactoryParams): Erstellt, um die Konfigurationen der RSA-Fabrik zu trennen --- .../Security/IRSAFactory.cs | 16 +-- DigitalData.Core.Security/AsymCryptService.cs | 5 +- DigitalData.Core.Security/RSAFactory.cs | 103 ++++++++---------- DigitalData.Core.Security/RSAFactoryParams.cs | 27 +++++ 4 files changed, 74 insertions(+), 77 deletions(-) create mode 100644 DigitalData.Core.Security/RSAFactoryParams.cs diff --git a/DigitalData.Core.Abstractions/Security/IRSAFactory.cs b/DigitalData.Core.Abstractions/Security/IRSAFactory.cs index 6293b66..0dfea9d 100644 --- a/DigitalData.Core.Abstractions/Security/IRSAFactory.cs +++ b/DigitalData.Core.Abstractions/Security/IRSAFactory.cs @@ -2,22 +2,8 @@ namespace DigitalData.Core.Abstractions.Security { - public interface IRSAFactory + public interface IRSAFactory { - int KeySizeInBits { get; init; } - - string PbePassword { init; } - - PbeEncryptionAlgorithm PbeEncryptionAlgorithm { get; init; } - - HashAlgorithmName PbeHashAlgorithmName { get; init; } - - int PbeIterationCount { get; init; } - - PbeParameters PbeParameters { get; } - - string EncryptedPrivateKeyPemLabel { get; init; } - string CreateRSAPrivateKeyPem(int? keySizeInBits = null); string CreateEncryptedPrivateKeyPem( diff --git a/DigitalData.Core.Security/AsymCryptService.cs b/DigitalData.Core.Security/AsymCryptService.cs index 2b867a4..32d65fb 100644 --- a/DigitalData.Core.Security/AsymCryptService.cs +++ b/DigitalData.Core.Security/AsymCryptService.cs @@ -1,9 +1,10 @@ using DigitalData.Core.Abstractions.Security; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; namespace DigitalData.Core.Security { - public class AsymCryptService : RSAFactory, IAsymCryptService, IRSAFactory + public class AsymCryptService : RSAFactory, IAsymCryptService, IRSAFactory where TRSAFactoryParams : RSAFactoryParams { private readonly IDictionary _decryptors; @@ -11,7 +12,7 @@ namespace DigitalData.Core.Security public Func RSAKeyNameFormatter { get; } - public AsymCryptService(IDictionary decryptors, Func rsaKeyNameFormatter, ILogger? logger = null) : base() + public AsymCryptService(IOptions options, IDictionary decryptors, Func rsaKeyNameFormatter, ILogger>? logger = null) : base(options) { _decryptors = decryptors ?? new Dictionary(); diff --git a/DigitalData.Core.Security/RSAFactory.cs b/DigitalData.Core.Security/RSAFactory.cs index 846f3a5..e5c0250 100644 --- a/DigitalData.Core.Security/RSAFactory.cs +++ b/DigitalData.Core.Security/RSAFactory.cs @@ -1,35 +1,53 @@ using DigitalData.Core.Abstractions.Security; +using Microsoft.Extensions.Options; using System.Security.Cryptography; using System.Text; namespace DigitalData.Core.Security { - public class RSAFactory : IRSAFactory + public class RSAFactory : IRSAFactory where TRSAFactoryParams : RSAFactoryParams { - private static readonly Lazy LazyInstance = new(() => new()); + private static readonly Lazy> LazyInstance = new(() => new(Options.Create(new()))); - public static RSAFactory Static => LazyInstance.Value; + public static RSAFactory Static => LazyInstance.Value; - public static readonly string DefaultEncryptedPrivateKeyFileTag = "enc-private"; + private readonly RSAFactoryParams _params; - public static readonly string DefaultPrivateKeyFileTag = "private"; + private readonly IEnumerable _lowerFileTags; - public static readonly string DefaultPublicKeyFileTag = "public"; - - public static readonly IEnumerable KeyFileTags = new string[] { DefaultEncryptedPrivateKeyFileTag, DefaultPrivateKeyFileTag, DefaultPublicKeyFileTag }; + //TODO: make the validation using regex + public static string DefaultRSAKeyNameFormatter(string separator, string issuer, string audience, string encryptedPrivateKeyFileTag, string privateKeyFileTag, string publicKeyFileTag, bool isPrivate = true, Version? passwordVersion = null) + { + var sb = new StringBuilder(issuer.Length + audience.Length + separator.Length * 2 + 20); + sb.Append(issuer).Append(separator).Append(audience).Append(separator); - private static readonly Lazy> LazyLowerFileTags = new(() => KeyFileTags.Select(tag => tag.ToLower())); + if (passwordVersion is null && isPrivate) + sb.Append(privateKeyFileTag); + else if (isPrivate) + sb.Append(encryptedPrivateKeyFileTag).Append(separator).Append(passwordVersion); + else if (passwordVersion is null) + sb.Append(publicKeyFileTag); + else + sb.Append(publicKeyFileTag).Append(separator).Append(passwordVersion); - public static readonly string DefaultRSAKeyNameSeparator = "-_-"; + return sb.ToString(); + } - //TODO: make the validation using regex - public static string DefaultRSAKeyNameFormatter(string issuer, string audience, bool isPrivate = true, Version? passwordVersion = null, string? separator = null) + private readonly PbeParameters _pbeParameters; + + public RSAFactory(IOptions options) { - separator ??= DefaultRSAKeyNameSeparator; + _params = options.Value; + var keyFileTags = new string[] { _params.EncryptedPrivateKeyFileTag, _params.PrivateKeyFileTag, _params.PublicKeyFileTag }; + _lowerFileTags = keyFileTags.Select(tag => tag.ToLower()); + _pbeParameters = new PbeParameters(_params.PbeEncryptionAlgorithm, _params.PbeHashAlgorithmName, _params.PbeIterationCount); + } + public void ValidateFormatterParams(string issuer, string audience) + { void ValidateForbidden(string value, string paramName) { - if (Path.GetInvalidFileNameChars().Any(value.Contains) || LazyLowerFileTags.Value.Any(tag => value.ToLower().Contains(tag))) + if (Path.GetInvalidFileNameChars().Any(value.Contains) || _lowerFileTags.Any(tag => value.ToLower().Contains(tag))) throw new ArgumentException($"RSA decryptor key name creation is forbidden. The {paramName} contains forbidden characters that are not allowed in file naming.", paramName); } @@ -41,49 +59,14 @@ namespace DigitalData.Core.Security ValidateForbidden(issuer, nameof(issuer)); ValidateForbidden(audience, nameof(audience)); - ValidateForbidden(separator, nameof(separator)); - - ValidateSeparator(issuer, nameof(issuer), separator); - ValidateSeparator(audience, nameof(audience), separator); - - var sb = new StringBuilder(issuer.Length + audience.Length + separator.Length * 2 + 20); - sb.Append(issuer).Append(separator).Append(audience).Append(separator); + ValidateForbidden(_params.RSAKeyNameSeparator, nameof(_params.RSAKeyNameSeparator)); - if (passwordVersion is null && isPrivate) - sb.Append(DefaultPrivateKeyFileTag); - else if (isPrivate) - sb.Append(DefaultEncryptedPrivateKeyFileTag).Append(separator).Append(passwordVersion); - else if (passwordVersion is null) - sb.Append(DefaultPublicKeyFileTag); - else - sb.Append(DefaultPublicKeyFileTag).Append(separator).Append(passwordVersion); - - return sb.ToString(); - } - - 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 _lazyPbeParameters; - - public PbeParameters PbeParameters => _lazyPbeParameters.Value; - - public string EncryptedPrivateKeyPemLabel { get; init; } = "ENCRYPTED PRIVATE KEY"; - - internal RSAFactory() - { - _lazyPbeParameters = new(() => new PbeParameters(PbeEncryptionAlgorithm, PbeHashAlgorithmName, PbeIterationCount)); + ValidateSeparator(issuer, nameof(issuer), _params.RSAKeyNameSeparator); + ValidateSeparator(audience, nameof(audience), _params.RSAKeyNameSeparator); } public string CreateRSAPrivateKeyPem(int? keySizeInBits = null) - => RSA.Create(keySizeInBits ?? KeySizeInBits).ExportRSAPrivateKeyPem(); + => RSA.Create(keySizeInBits ?? _params.KeySizeInBits).ExportRSAPrivateKeyPem(); public string CreateEncryptedPrivateKeyPem( int? keySizeInBits = null, @@ -92,18 +75,18 @@ namespace DigitalData.Core.Security HashAlgorithmName? hashAlgorithmName = null, int? iterationCount = null) { - password ??= PbePassword; + password ??= _params.PbePassword; var pbeParameters = (pbeEncryptionAlgorithm is null && hashAlgorithmName is null && iterationCount is null) ? new PbeParameters( - pbeEncryptionAlgorithm ?? PbeEncryptionAlgorithm, - hashAlgorithmName ?? PbeHashAlgorithmName, - iterationCount ?? PbeIterationCount) - : PbeParameters; + pbeEncryptionAlgorithm ?? _params.PbeEncryptionAlgorithm, + hashAlgorithmName ?? _params.PbeHashAlgorithmName, + iterationCount ?? _params.PbeIterationCount) + : _pbeParameters; - var encryptedPrivateKey = RSA.Create(keySizeInBits ?? KeySizeInBits).ExportEncryptedPkcs8PrivateKey(password.AsSpan(), pbeParameters); + var encryptedPrivateKey = RSA.Create(keySizeInBits ?? _params.KeySizeInBits).ExportEncryptedPkcs8PrivateKey(password.AsSpan(), pbeParameters); - var pemChars = PemEncoding.Write(EncryptedPrivateKeyPemLabel, encryptedPrivateKey); + var pemChars = PemEncoding.Write(_params.EncryptedPrivateKeyPemLabel, encryptedPrivateKey); return new string(pemChars); } diff --git a/DigitalData.Core.Security/RSAFactoryParams.cs b/DigitalData.Core.Security/RSAFactoryParams.cs new file mode 100644 index 0000000..6673a90 --- /dev/null +++ b/DigitalData.Core.Security/RSAFactoryParams.cs @@ -0,0 +1,27 @@ +using System.Security.Cryptography; + +namespace DigitalData.Core.Security +{ + public class RSAFactoryParams + { + public string EncryptedPrivateKeyFileTag { get; init; } = "enc-private"; + + public string PrivateKeyFileTag { get; init; } = "private"; + + public string PublicKeyFileTag { get; init; } = "public"; + + public string RSAKeyNameSeparator { get; init; } = "-_-"; + + public int KeySizeInBits { get; init; } = 2048; + + public string PbePassword { internal 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; + + public string EncryptedPrivateKeyPemLabel { get; init; } = "ENCRYPTED PRIVATE KEY"; + } +} \ No newline at end of file From 3aa5ad782ffc973f0547add957b3b2f64de47791 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Tue, 3 Dec 2024 09:54:42 +0100 Subject: [PATCH 04/61] refactor: Aktualisierung der `DefaultRSAKeyNameFormatter` Signatur und Logik in `RSAFactory` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Die Methode `DefaultRSAKeyNameFormatter` wurde geändert, um einen `visibilityTag`- und `expiration`-Parameter aufzunehmen. - Redundante bedingte Logik für das Anhängen von Tags wurde entfernt und der Formatter für bessere Lesbarkeit und Skalierbarkeit umstrukturiert. - Gewährleistung der Abwärtskompatibilität mit der Versionierung durch bedingte Behandlung von `passwordVersion`. --- DigitalData.Core.Security/RSAFactory.cs | 32 ++++++++++--------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/DigitalData.Core.Security/RSAFactory.cs b/DigitalData.Core.Security/RSAFactory.cs index e5c0250..3a5af5f 100644 --- a/DigitalData.Core.Security/RSAFactory.cs +++ b/DigitalData.Core.Security/RSAFactory.cs @@ -7,32 +7,25 @@ namespace DigitalData.Core.Security { public class RSAFactory : IRSAFactory where TRSAFactoryParams : RSAFactoryParams { - private static readonly Lazy> LazyInstance = new(() => new(Options.Create(new()))); - - public static RSAFactory Static => LazyInstance.Value; - - private readonly RSAFactoryParams _params; - - private readonly IEnumerable _lowerFileTags; - - //TODO: make the validation using regex - public static string DefaultRSAKeyNameFormatter(string separator, string issuer, string audience, string encryptedPrivateKeyFileTag, string privateKeyFileTag, string publicKeyFileTag, bool isPrivate = true, Version? passwordVersion = null) + public static string DefaultRSAKeyNameFormatter(string separator, string issuer, string audience, string visibilityTag, DateOnly expiration, Version? passwordVersion = null) { var sb = new StringBuilder(issuer.Length + audience.Length + separator.Length * 2 + 20); - sb.Append(issuer).Append(separator).Append(audience).Append(separator); + sb.Append(issuer).Append(separator).Append(audience).Append(separator).Append(visibilityTag).Append(separator).Append(expiration); - if (passwordVersion is null && isPrivate) - sb.Append(privateKeyFileTag); - else if (isPrivate) - sb.Append(encryptedPrivateKeyFileTag).Append(separator).Append(passwordVersion); - else if (passwordVersion is null) - sb.Append(publicKeyFileTag); - else - sb.Append(publicKeyFileTag).Append(separator).Append(passwordVersion); + if (passwordVersion is not null) + sb.Append(separator).Append(passwordVersion); return sb.ToString(); } + private static readonly Lazy> LazyInstance = new(() => new(Options.Create(new()))); + + public static RSAFactory Static => LazyInstance.Value; + + private readonly RSAFactoryParams _params; + + private readonly IEnumerable _lowerFileTags; + private readonly PbeParameters _pbeParameters; public RSAFactory(IOptions options) @@ -43,6 +36,7 @@ namespace DigitalData.Core.Security _pbeParameters = new PbeParameters(_params.PbeEncryptionAlgorithm, _params.PbeHashAlgorithmName, _params.PbeIterationCount); } + //TODO: make the validation using regex public void ValidateFormatterParams(string issuer, string audience) { void ValidateForbidden(string value, string paramName) From 09406ca5058ec62b5e0069ff133f86b8a2ad447a Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Tue, 3 Dec 2024 10:07:58 +0100 Subject: [PATCH 05/61] =?UTF-8?q?feat(IAsymCryptService):=20Generischer=20?= =?UTF-8?q?Typ=20TParams=20hinzugef=C3=BCgt.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DigitalData.Core.Abstractions/Security/IAsymCryptService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DigitalData.Core.Abstractions/Security/IAsymCryptService.cs b/DigitalData.Core.Abstractions/Security/IAsymCryptService.cs index ef8ecbc..b04281b 100644 --- a/DigitalData.Core.Abstractions/Security/IAsymCryptService.cs +++ b/DigitalData.Core.Abstractions/Security/IAsymCryptService.cs @@ -1,6 +1,6 @@ namespace DigitalData.Core.Abstractions.Security { - public interface IAsymCryptService : IRSAFactory + public interface IAsymCryptService : IRSAFactory { /// /// Gets the formatter function for generating RSA key names. From 6873bac8a1326408767bc6ad0a71c2a018ad8724 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Tue, 3 Dec 2024 10:12:51 +0100 Subject: [PATCH 06/61] =?UTF-8?q?feat(AsymCryptParams):=20Erstellt=20als?= =?UTF-8?q?=20spezifizierte=20Optionen=20f=C3=BCr=20AsymCryptService?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DigitalData.Core.Security/AsymCryptParams.cs | 6 ++++++ DigitalData.Core.Security/AsymCryptService.cs | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 DigitalData.Core.Security/AsymCryptParams.cs diff --git a/DigitalData.Core.Security/AsymCryptParams.cs b/DigitalData.Core.Security/AsymCryptParams.cs new file mode 100644 index 0000000..b5d14aa --- /dev/null +++ b/DigitalData.Core.Security/AsymCryptParams.cs @@ -0,0 +1,6 @@ +namespace DigitalData.Core.Security +{ + public class AsymCryptParams : RSAFactoryParams + { + } +} \ No newline at end of file diff --git a/DigitalData.Core.Security/AsymCryptService.cs b/DigitalData.Core.Security/AsymCryptService.cs index 32d65fb..9a7454f 100644 --- a/DigitalData.Core.Security/AsymCryptService.cs +++ b/DigitalData.Core.Security/AsymCryptService.cs @@ -4,7 +4,7 @@ using Microsoft.Extensions.Options; namespace DigitalData.Core.Security { - public class AsymCryptService : RSAFactory, IAsymCryptService, IRSAFactory where TRSAFactoryParams : RSAFactoryParams + public class AsymCryptService : RSAFactory, IAsymCryptService, IRSAFactory where TAsymCryptParams : AsymCryptParams { private readonly IDictionary _decryptors; @@ -12,7 +12,7 @@ namespace DigitalData.Core.Security public Func RSAKeyNameFormatter { get; } - public AsymCryptService(IOptions options, IDictionary decryptors, Func rsaKeyNameFormatter, ILogger>? logger = null) : base(options) + public AsymCryptService(IOptions options, IDictionary decryptors, Func rsaKeyNameFormatter, ILogger>? logger = null) : base(options) { _decryptors = decryptors ?? new Dictionary(); From 343560ed623cfa8cc27ab76c95189ff928cc46b9 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Tue, 3 Dec 2024 10:24:49 +0100 Subject: [PATCH 07/61] =?UTF-8?q?feat(AsymCryptParams):=20ReadOrCreateDirs?= =?UTF-8?q?-Eigenschaft=20zu=20params=20hinzugef=C3=BCgt,=20um=20die=20Akt?= =?UTF-8?q?ualisierung=20von=20Entschl=C3=BCsselungsprogrammen=20zu=20auto?= =?UTF-8?q?matisieren?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DigitalData.Core.Security/AsymCryptParams.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/DigitalData.Core.Security/AsymCryptParams.cs b/DigitalData.Core.Security/AsymCryptParams.cs index b5d14aa..07abe5e 100644 --- a/DigitalData.Core.Security/AsymCryptParams.cs +++ b/DigitalData.Core.Security/AsymCryptParams.cs @@ -2,5 +2,6 @@ { public class AsymCryptParams : RSAFactoryParams { + public IEnumerable? ReadOrCreateDirs { get; init; } } } \ No newline at end of file From c6942164e294a77ede7852699cecae308e6aa011 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Tue, 3 Dec 2024 10:29:40 +0100 Subject: [PATCH 08/61] =?UTF-8?q?refactor(RSAFactory):=20=5Fparams=20wurde?= =?UTF-8?q?=20gesch=C3=BCtzt=20und=20generisch=20f=C3=BCr=20die=20Verwendu?= =?UTF-8?q?ng=20in=20geerbten=20Klassen.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DigitalData.Core.Security/RSAFactory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DigitalData.Core.Security/RSAFactory.cs b/DigitalData.Core.Security/RSAFactory.cs index 3a5af5f..452ce6c 100644 --- a/DigitalData.Core.Security/RSAFactory.cs +++ b/DigitalData.Core.Security/RSAFactory.cs @@ -22,7 +22,7 @@ namespace DigitalData.Core.Security public static RSAFactory Static => LazyInstance.Value; - private readonly RSAFactoryParams _params; + protected readonly TRSAFactoryParams _params; private readonly IEnumerable _lowerFileTags; From 1a941b47280ce4c3846798e2f56e1f9c83eab322 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Tue, 3 Dec 2024 10:45:04 +0100 Subject: [PATCH 09/61] feat(ReadOrCreateDirectory): Erstellt, um alle pem-Dateien aus dem Ordner zu lesen und neu zu erstellen, wenn die angegebenen Dateien nicht vorhanden sind. --- DigitalData.Core.Security/AsymCryptParams.cs | 2 +- DigitalData.Core.Security/ReadOrCreateDirectory.cs | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 DigitalData.Core.Security/ReadOrCreateDirectory.cs diff --git a/DigitalData.Core.Security/AsymCryptParams.cs b/DigitalData.Core.Security/AsymCryptParams.cs index 07abe5e..dfe0991 100644 --- a/DigitalData.Core.Security/AsymCryptParams.cs +++ b/DigitalData.Core.Security/AsymCryptParams.cs @@ -2,6 +2,6 @@ { public class AsymCryptParams : RSAFactoryParams { - public IEnumerable? ReadOrCreateDirs { get; init; } + public IEnumerable ReadOrCreateDirs { get; init; } = new List(); } } \ No newline at end of file diff --git a/DigitalData.Core.Security/ReadOrCreateDirectory.cs b/DigitalData.Core.Security/ReadOrCreateDirectory.cs new file mode 100644 index 0000000..c53971e --- /dev/null +++ b/DigitalData.Core.Security/ReadOrCreateDirectory.cs @@ -0,0 +1,9 @@ +namespace DigitalData.Core.Security +{ + public class ReadOrCreateDirectory + { + public required string Dir { get; init; } + + public IEnumerable ReadOrCreateFiles { get; init; } = new List(); + } +} \ No newline at end of file From 9396f48f46004d5575b86d86f17eb9b171fc4d50 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 00:02:03 +0100 Subject: [PATCH 10/61] feat(Core.Security.DIExtensions): Arrangierte DI-Erweiterung --- DigitalData.Core.Security/DIExtensions.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/DigitalData.Core.Security/DIExtensions.cs b/DigitalData.Core.Security/DIExtensions.cs index 28f4596..1a75545 100644 --- a/DigitalData.Core.Security/DIExtensions.cs +++ b/DigitalData.Core.Security/DIExtensions.cs @@ -6,11 +6,10 @@ namespace DigitalData.Core.Security { public static class DIExtensions { - public static IServiceCollection AddSecurity(this IServiceCollection services) + public static IServiceCollection AddAsymCryptService(this IServiceCollection services) + where TAsymCryptParams : AsymCryptParams { - services.TryAddScoped(sp => RSAFactory.Static); - services.TryAddScoped(); - + services.TryAddScoped, AsymCryptService>(); return services; } } From 0c451cb834c9ed35b91f3290ae24c736b8ff6879 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 00:19:02 +0100 Subject: [PATCH 11/61] =?UTF-8?q?feat(Core.Security.DIExtensions):=20Injek?= =?UTF-8?q?tion=20von=20Parametern=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DigitalData.Core.Security/DIExtensions.cs | 27 ++++++++++++++++++- .../DigitalData.Core.Security.csproj | 4 +++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/DigitalData.Core.Security/DIExtensions.cs b/DigitalData.Core.Security/DIExtensions.cs index 1a75545..7b92f69 100644 --- a/DigitalData.Core.Security/DIExtensions.cs +++ b/DigitalData.Core.Security/DIExtensions.cs @@ -1,16 +1,41 @@ using DigitalData.Core.Abstractions.Security; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Options; namespace DigitalData.Core.Security { public static class DIExtensions { - public static IServiceCollection AddAsymCryptService(this IServiceCollection services) + private static IServiceCollection AddAsymCryptService(this IServiceCollection services) where TAsymCryptParams : AsymCryptParams { services.TryAddScoped, AsymCryptService>(); return services; } + + public static IServiceCollection AddAsymCryptService(this IServiceCollection services, IConfigurationSection section) + where TAsymCryptParams : AsymCryptParams + => services.Configure(section).AddAsymCryptService(); + + public static IServiceCollection AddAsymCryptService(this IServiceCollection services, TAsymCryptParams param) + where TAsymCryptParams : AsymCryptParams + => services.AddSingleton(Options.Create(param)).AddAsymCryptService(); + + private static IServiceCollection AddRSAFactory(this IServiceCollection services) + where TRSAFactoryParams : RSAFactoryParams + { + services.TryAddScoped, RSAFactory>(); + return services; + } + + public static IServiceCollection AddRSAFactory(this IServiceCollection services, IConfigurationSection section) + where TRSAFactoryParams : RSAFactoryParams + => services.Configure(section).AddRSAFactory(); + + public static IServiceCollection AddRSAFactory(this IServiceCollection services, TRSAFactoryParams param) + where TRSAFactoryParams : RSAFactoryParams + => services.AddSingleton(Options.Create(param)).AddRSAFactory(); } } \ No newline at end of file diff --git a/DigitalData.Core.Security/DigitalData.Core.Security.csproj b/DigitalData.Core.Security/DigitalData.Core.Security.csproj index 3e2378e..c198a40 100644 --- a/DigitalData.Core.Security/DigitalData.Core.Security.csproj +++ b/DigitalData.Core.Security/DigitalData.Core.Security.csproj @@ -6,6 +6,10 @@ enable + + + + From c895d2df0e9907c5684f7233889bcb5de0413e0b Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 00:23:28 +0100 Subject: [PATCH 12/61] =?UTF-8?q?feat(RSAFactory):=20Formatierer=20f=C3=BC?= =?UTF-8?q?r=20Schl=C3=BCsselnamen=20entfernen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DigitalData.Core.Security/RSAFactory.cs | 39 ------------------------- 1 file changed, 39 deletions(-) diff --git a/DigitalData.Core.Security/RSAFactory.cs b/DigitalData.Core.Security/RSAFactory.cs index 452ce6c..c56cc13 100644 --- a/DigitalData.Core.Security/RSAFactory.cs +++ b/DigitalData.Core.Security/RSAFactory.cs @@ -1,64 +1,25 @@ using DigitalData.Core.Abstractions.Security; using Microsoft.Extensions.Options; using System.Security.Cryptography; -using System.Text; namespace DigitalData.Core.Security { public class RSAFactory : IRSAFactory where TRSAFactoryParams : RSAFactoryParams { - public static string DefaultRSAKeyNameFormatter(string separator, string issuer, string audience, string visibilityTag, DateOnly expiration, Version? passwordVersion = null) - { - var sb = new StringBuilder(issuer.Length + audience.Length + separator.Length * 2 + 20); - sb.Append(issuer).Append(separator).Append(audience).Append(separator).Append(visibilityTag).Append(separator).Append(expiration); - - if (passwordVersion is not null) - sb.Append(separator).Append(passwordVersion); - - return sb.ToString(); - } - private static readonly Lazy> LazyInstance = new(() => new(Options.Create(new()))); public static RSAFactory Static => LazyInstance.Value; protected readonly TRSAFactoryParams _params; - - private readonly IEnumerable _lowerFileTags; private readonly PbeParameters _pbeParameters; public RSAFactory(IOptions options) { _params = options.Value; - var keyFileTags = new string[] { _params.EncryptedPrivateKeyFileTag, _params.PrivateKeyFileTag, _params.PublicKeyFileTag }; - _lowerFileTags = keyFileTags.Select(tag => tag.ToLower()); _pbeParameters = new PbeParameters(_params.PbeEncryptionAlgorithm, _params.PbeHashAlgorithmName, _params.PbeIterationCount); } - //TODO: make the validation using regex - public void ValidateFormatterParams(string issuer, string audience) - { - void ValidateForbidden(string value, string paramName) - { - if (Path.GetInvalidFileNameChars().Any(value.Contains) || _lowerFileTags.Any(tag => value.ToLower().Contains(tag))) - throw new ArgumentException($"RSA decryptor key name creation is forbidden. The {paramName} contains forbidden characters that are not allowed in file naming.", paramName); - } - - static void ValidateSeparator(string value, string paramName, string separator) - { - if (value.Contains(separator)) - throw new ArgumentException($"RSA decryptor key name creation is forbidden. The {paramName} contains separator characters ({separator}) that are not allowed in file naming.", paramName); - } - - ValidateForbidden(issuer, nameof(issuer)); - ValidateForbidden(audience, nameof(audience)); - ValidateForbidden(_params.RSAKeyNameSeparator, nameof(_params.RSAKeyNameSeparator)); - - ValidateSeparator(issuer, nameof(issuer), _params.RSAKeyNameSeparator); - ValidateSeparator(audience, nameof(audience), _params.RSAKeyNameSeparator); - } - public string CreateRSAPrivateKeyPem(int? keySizeInBits = null) => RSA.Create(keySizeInBits ?? _params.KeySizeInBits).ExportRSAPrivateKeyPem(); From 65989b23b35163ace15764fb1fcf7ae449596874 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 00:43:42 +0100 Subject: [PATCH 13/61] =?UTF-8?q?refactor(RSAFactoryParams):=20Eigenschaft?= =?UTF-8?q?=20PbeParameters=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DigitalData.Core.Security.Extensions/RSAExtensions.cs | 4 ++-- DigitalData.Core.Security/RSAFactory.cs | 10 ++-------- DigitalData.Core.Security/RSAFactoryParams.cs | 7 +++++++ 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/DigitalData.Core.Security.Extensions/RSAExtensions.cs b/DigitalData.Core.Security.Extensions/RSAExtensions.cs index be2ef74..afad98a 100644 --- a/DigitalData.Core.Security.Extensions/RSAExtensions.cs +++ b/DigitalData.Core.Security.Extensions/RSAExtensions.cs @@ -13,10 +13,10 @@ namespace DigitalData.Core.Security.Extensions return rsa; } - public static IRSADecryptor GetRSADecryptor(this IAsymCryptService factory, string issuer, string audience, Version? version = null, string? seperator = null) + public static IRSADecryptor GetRSADecryptor(this IAsymCryptService factory, string issuer, string audience, Version? version = null, string? seperator = null) => factory[factory.RSAKeyNameFormatter(issuer, audience, true, version, seperator)]; - public static bool TryGetRSADecryptor(this IAsymCryptService factory, string issuer, string audience, out IRSADecryptor? decryptor, Version? version = null, string? seperator = null) + public static bool TryGetRSADecryptor(this IAsymCryptService factory, string issuer, string audience, out IRSADecryptor? decryptor, Version? version = null, string? seperator = null) => factory.TryGetRSADecryptor(factory.RSAKeyNameFormatter(issuer, audience, true, version, seperator), out decryptor); private static string CreatePath(string filename, string? directory = null) diff --git a/DigitalData.Core.Security/RSAFactory.cs b/DigitalData.Core.Security/RSAFactory.cs index c56cc13..c403549 100644 --- a/DigitalData.Core.Security/RSAFactory.cs +++ b/DigitalData.Core.Security/RSAFactory.cs @@ -12,13 +12,7 @@ namespace DigitalData.Core.Security protected readonly TRSAFactoryParams _params; - private readonly PbeParameters _pbeParameters; - - public RSAFactory(IOptions options) - { - _params = options.Value; - _pbeParameters = new PbeParameters(_params.PbeEncryptionAlgorithm, _params.PbeHashAlgorithmName, _params.PbeIterationCount); - } + public RSAFactory(IOptions options) => _params = options.Value; public string CreateRSAPrivateKeyPem(int? keySizeInBits = null) => RSA.Create(keySizeInBits ?? _params.KeySizeInBits).ExportRSAPrivateKeyPem(); @@ -37,7 +31,7 @@ namespace DigitalData.Core.Security pbeEncryptionAlgorithm ?? _params.PbeEncryptionAlgorithm, hashAlgorithmName ?? _params.PbeHashAlgorithmName, iterationCount ?? _params.PbeIterationCount) - : _pbeParameters; + : _params.PbeParameters; var encryptedPrivateKey = RSA.Create(keySizeInBits ?? _params.KeySizeInBits).ExportEncryptedPkcs8PrivateKey(password.AsSpan(), pbeParameters); diff --git a/DigitalData.Core.Security/RSAFactoryParams.cs b/DigitalData.Core.Security/RSAFactoryParams.cs index 6673a90..6a093af 100644 --- a/DigitalData.Core.Security/RSAFactoryParams.cs +++ b/DigitalData.Core.Security/RSAFactoryParams.cs @@ -23,5 +23,12 @@ namespace DigitalData.Core.Security public int PbeIterationCount { get; init; } = 100_000; public string EncryptedPrivateKeyPemLabel { get; init; } = "ENCRYPTED PRIVATE KEY"; + + private readonly Lazy _lazyPbeParameters; + + public PbeParameters PbeParameters => _lazyPbeParameters.Value; + + public RSAFactoryParams() + => _lazyPbeParameters = new(() => new PbeParameters(PbeEncryptionAlgorithm, PbeHashAlgorithmName, PbeIterationCount)); } } \ No newline at end of file From 750f7bc20c3ff481af38e7ee0ae6d7e5b9419855 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 00:53:27 +0100 Subject: [PATCH 14/61] =?UTF-8?q?refactor(AsymCryptService):=20Entschl?= =?UTF-8?q?=C3=BCsselungsinjektion=20entfernt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Security/IAsymCryptService.cs | 18 ++---------------- .../RSAExtensions.cs | 8 +------- DigitalData.Core.Security/AsymCryptService.cs | 11 +++-------- 3 files changed, 6 insertions(+), 31 deletions(-) diff --git a/DigitalData.Core.Abstractions/Security/IAsymCryptService.cs b/DigitalData.Core.Abstractions/Security/IAsymCryptService.cs index b04281b..9e95d14 100644 --- a/DigitalData.Core.Abstractions/Security/IAsymCryptService.cs +++ b/DigitalData.Core.Abstractions/Security/IAsymCryptService.cs @@ -1,22 +1,8 @@ namespace DigitalData.Core.Abstractions.Security { public interface IAsymCryptService : IRSAFactory - { - /// - /// Gets the formatter function for generating RSA key names. - /// This formatter takes an issuer, audience, isPrivate, and optional version and separator - /// to produce a formatted string used for the key naming convention. - /// - /// A string representing the issuer of the key. It should not contain invalid file name characters or the separator. - /// A string representing the audience for which the key is intended. It should not contain invalid file name characters or the separator. - /// An bool to check if the key is private. - /// An instance of the interface, which is used to keep the version of Pbe password. - /// An optional string separator used to separate the issuer and audience. The default is "-_-". It should not be included in the issuer or audience strings. - /// A formatted string combining the issuer, audience, and separator, which adheres to valid file naming rules. - /// Thrown when the issuer, audience, or separator contains invalid characters or when the separator is present within the issuer or audience. - Func RSAKeyNameFormatter { get; } - - IRSADecryptor this[string key] { get; } + { + IRSADecryptor this[string key] { get; } bool TryGetRSADecryptor(string key, out IRSADecryptor? decryptor); } diff --git a/DigitalData.Core.Security.Extensions/RSAExtensions.cs b/DigitalData.Core.Security.Extensions/RSAExtensions.cs index afad98a..47dcef5 100644 --- a/DigitalData.Core.Security.Extensions/RSAExtensions.cs +++ b/DigitalData.Core.Security.Extensions/RSAExtensions.cs @@ -12,13 +12,7 @@ namespace DigitalData.Core.Security.Extensions rsa.ImportFromPem(pem); return rsa; } - - public static IRSADecryptor GetRSADecryptor(this IAsymCryptService factory, string issuer, string audience, Version? version = null, string? seperator = null) - => factory[factory.RSAKeyNameFormatter(issuer, audience, true, version, seperator)]; - - public static bool TryGetRSADecryptor(this IAsymCryptService factory, string issuer, string audience, out IRSADecryptor? decryptor, Version? version = null, string? seperator = null) - => factory.TryGetRSADecryptor(factory.RSAKeyNameFormatter(issuer, audience, true, version, seperator), out decryptor); - + private static string CreatePath(string filename, string? directory = null) { directory ??= Environment.CurrentDirectory; diff --git a/DigitalData.Core.Security/AsymCryptService.cs b/DigitalData.Core.Security/AsymCryptService.cs index 9a7454f..d68561d 100644 --- a/DigitalData.Core.Security/AsymCryptService.cs +++ b/DigitalData.Core.Security/AsymCryptService.cs @@ -6,18 +6,13 @@ namespace DigitalData.Core.Security { public class AsymCryptService : RSAFactory, IAsymCryptService, IRSAFactory where TAsymCryptParams : AsymCryptParams { - private readonly IDictionary _decryptors; + private readonly Dictionary _decryptors; public IRSADecryptor this[string key] { get => _decryptors[key]; set => _decryptors[key] = value; } - public Func RSAKeyNameFormatter { get; } - - public AsymCryptService(IOptions options, IDictionary decryptors, Func rsaKeyNameFormatter, ILogger>? logger = null) : base(options) + public AsymCryptService(IOptions options, ILogger>? logger = null) : base(options) { - _decryptors = decryptors ?? new Dictionary(); - - RSAKeyNameFormatter = rsaKeyNameFormatter; - + _decryptors = new(); logger?.LogInformation("Core.Secrets version: {Version}, Created on: {CreationDate}.", Secrets.Version, Secrets.CreationDate.ToString("dd.MM.yyyy")); } From c03f39c1a9202ee01dc1afd67cef95c8edd10189 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 01:15:59 +0100 Subject: [PATCH 15/61] =?UTF-8?q?feat(RSACryptographer):=20Verfall=20hinzu?= =?UTF-8?q?gef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DigitalData.Core.Security/RSACryptographer.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/DigitalData.Core.Security/RSACryptographer.cs b/DigitalData.Core.Security/RSACryptographer.cs index 55161cc..ed6c72d 100644 --- a/DigitalData.Core.Security/RSACryptographer.cs +++ b/DigitalData.Core.Security/RSACryptographer.cs @@ -11,6 +11,21 @@ namespace DigitalData.Core.Security protected virtual RSA RSA { get; } = RSA.Create(); + private DateOnly? _expiration; + + public DateOnly? Expiration + { + get => _expiration; + init + { + + if (value <= DateOnly.FromDateTime(DateTime.Now)) + throw new InvalidOperationException("The expiration date has already passed."); + + _expiration = value; + } + } + internal RSACryptographer() { } } } \ No newline at end of file From cc3d1f58d3b548e0b9e7c7bef757f94e6aa83e30 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 01:21:49 +0100 Subject: [PATCH 16/61] =?UTF-8?q?feat(RSACryptographer):=20Version=20hinzu?= =?UTF-8?q?gef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DigitalData.Core.Security/RSACryptographer.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/DigitalData.Core.Security/RSACryptographer.cs b/DigitalData.Core.Security/RSACryptographer.cs index ed6c72d..e5cd2b8 100644 --- a/DigitalData.Core.Security/RSACryptographer.cs +++ b/DigitalData.Core.Security/RSACryptographer.cs @@ -1,5 +1,6 @@ using DigitalData.Core.Abstractions.Security; using System.Security.Cryptography; +using System.Text.Json; namespace DigitalData.Core.Security { @@ -20,12 +21,26 @@ namespace DigitalData.Core.Security { if (value <= DateOnly.FromDateTime(DateTime.Now)) - throw new InvalidOperationException("The expiration date has already passed."); + throw new InvalidOperationException($"Cryptographer expiration date has already passed. Cryptographer: {JsonSerializer.Serialize(this)}"); _expiration = value; } } + private Version? _version; + + public Version? Version + { + get => _version; + init + { + if (value != Secrets.Version) + throw new InvalidOperationException($"Cryptographer version ({value}) does not match the expected version ({Secrets.Version}). Cryptographer: {JsonSerializer.Serialize(this)}"); + + _version = value; + } + } + internal RSACryptographer() { } } } \ No newline at end of file From 609cd29dc5446fe18bb656fe9d60bba39b2e9bbc Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 01:24:03 +0100 Subject: [PATCH 17/61] =?UTF-8?q?feat(RSACryptographer):=20Issuer=20und=20?= =?UTF-8?q?Audience=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DigitalData.Core.Security/RSACryptographer.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DigitalData.Core.Security/RSACryptographer.cs b/DigitalData.Core.Security/RSACryptographer.cs index e5cd2b8..ba316ee 100644 --- a/DigitalData.Core.Security/RSACryptographer.cs +++ b/DigitalData.Core.Security/RSACryptographer.cs @@ -12,6 +12,10 @@ namespace DigitalData.Core.Security protected virtual RSA RSA { get; } = RSA.Create(); + public string? Issuer { get; init; } + + public string? Audience { get; init; } + private DateOnly? _expiration; public DateOnly? Expiration From 3ffdd49a47eac165df34615a790f00af267f928a Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 01:28:22 +0100 Subject: [PATCH 18/61] =?UTF-8?q?feat:=20CryptographerType-Enum=20hinzugef?= =?UTF-8?q?=C3=BCgt,=20um=20Schl=C3=BCsseltypen=20darzustellen=20Schl?= =?UTF-8?q?=C3=BCssel=20zu=20kategorisieren.=20-=20Werte=20hinzugef=C3=BCg?= =?UTF-8?q?t:=20=20=20-=20`Private`=20f=C3=BCr=20private=20Schl=C3=BCssel.?= =?UTF-8?q?=20=20=20-=20`EncPrivate`=20f=C3=BCr=20verschl=C3=BCsselte=20pr?= =?UTF-8?q?ivate=20Schl=C3=BCssel.=20=20=20-=20`Public`=20f=C3=BCr=20?= =?UTF-8?q?=C3=B6ffentliche=20Schl=C3=BCssel.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DigitalData.Core.Security/CryptographicKeyType.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 DigitalData.Core.Security/CryptographicKeyType.cs diff --git a/DigitalData.Core.Security/CryptographicKeyType.cs b/DigitalData.Core.Security/CryptographicKeyType.cs new file mode 100644 index 0000000..4927c6c --- /dev/null +++ b/DigitalData.Core.Security/CryptographicKeyType.cs @@ -0,0 +1,12 @@ +namespace DigitalData.Core.Security +{ + namespace DigitalData.Core.Security + { + public enum CryptographicKeyType + { + PrivateKey, + EncryptedPrivateKey, + PublicKey + } + } +} \ No newline at end of file From c9548238bb9244f66b2a5d5847939c295a2b346c Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 09:13:54 +0100 Subject: [PATCH 19/61] =?UTF-8?q?Revert=20"feat:=20CryptographerType-Enum?= =?UTF-8?q?=20hinzugef=C3=BCgt,=20um=20Schl=C3=BCsseltypen=20darzustellen"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 3ffdd49a47eac165df34615a790f00af267f928a. --- DigitalData.Core.Security/CryptographicKeyType.cs | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 DigitalData.Core.Security/CryptographicKeyType.cs diff --git a/DigitalData.Core.Security/CryptographicKeyType.cs b/DigitalData.Core.Security/CryptographicKeyType.cs deleted file mode 100644 index 4927c6c..0000000 --- a/DigitalData.Core.Security/CryptographicKeyType.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace DigitalData.Core.Security -{ - namespace DigitalData.Core.Security - { - public enum CryptographicKeyType - { - PrivateKey, - EncryptedPrivateKey, - PublicKey - } - } -} \ No newline at end of file From 506685a0b59b313e6086f7b7d66467ae8eb249be Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 09:17:44 +0100 Subject: [PATCH 20/61] refactor(RSACryptographer): Verfallsdatum und Version entfernt --- DigitalData.Core.Security/RSACryptographer.cs | 32 +------------------ DigitalData.Core.Security/RSADecryptor.cs | 3 ++ DigitalData.Core.Security/RSAEncryptor.cs | 3 ++ 3 files changed, 7 insertions(+), 31 deletions(-) diff --git a/DigitalData.Core.Security/RSACryptographer.cs b/DigitalData.Core.Security/RSACryptographer.cs index ba316ee..1b357bd 100644 --- a/DigitalData.Core.Security/RSACryptographer.cs +++ b/DigitalData.Core.Security/RSACryptographer.cs @@ -1,6 +1,5 @@ using DigitalData.Core.Abstractions.Security; using System.Security.Cryptography; -using System.Text.Json; namespace DigitalData.Core.Security { @@ -15,36 +14,7 @@ namespace DigitalData.Core.Security public string? Issuer { get; init; } public string? Audience { get; init; } - - private DateOnly? _expiration; - - public DateOnly? Expiration - { - get => _expiration; - init - { - - if (value <= DateOnly.FromDateTime(DateTime.Now)) - throw new InvalidOperationException($"Cryptographer expiration date has already passed. Cryptographer: {JsonSerializer.Serialize(this)}"); - - _expiration = value; - } - } - - private Version? _version; - - public Version? Version - { - get => _version; - init - { - if (value != Secrets.Version) - throw new InvalidOperationException($"Cryptographer version ({value}) does not match the expected version ({Secrets.Version}). Cryptographer: {JsonSerializer.Serialize(this)}"); - - _version = value; - } - } - + internal RSACryptographer() { } } } \ No newline at end of file diff --git a/DigitalData.Core.Security/RSADecryptor.cs b/DigitalData.Core.Security/RSADecryptor.cs index a527fe5..60bfc71 100644 --- a/DigitalData.Core.Security/RSADecryptor.cs +++ b/DigitalData.Core.Security/RSADecryptor.cs @@ -1,4 +1,5 @@ using DigitalData.Core.Abstractions.Security; +using DigitalData.Core.Security.DigitalData.Core.Security; using DigitalData.Core.Security.Extensions; using System.Security.Cryptography; @@ -31,6 +32,8 @@ namespace DigitalData.Core.Security protected override RSA RSA => lazyRSA.Value; + public override CryptKeyType KeyType => IsEncrypted ? CryptKeyType.EncryptedPrivate : CryptKeyType.Private; + public RSADecryptor() { _lazyEncryptor = new(() => new RSAEncryptor() diff --git a/DigitalData.Core.Security/RSAEncryptor.cs b/DigitalData.Core.Security/RSAEncryptor.cs index 7783902..36e6177 100644 --- a/DigitalData.Core.Security/RSAEncryptor.cs +++ b/DigitalData.Core.Security/RSAEncryptor.cs @@ -1,4 +1,5 @@ using DigitalData.Core.Abstractions.Security; +using DigitalData.Core.Security.DigitalData.Core.Security; using DigitalData.Core.Security.Extensions; namespace DigitalData.Core.Security @@ -15,6 +16,8 @@ namespace DigitalData.Core.Security } } + public override CryptKeyType KeyType => CryptKeyType.Public; + public byte[] Encrypt(byte[] data) => RSA.Encrypt(data, Padding); public string Encrypt(string data) => RSA.Encrypt(data.Base64ToByte(), Padding).BytesToString(); From aa9951f2424d348d8241ecf70c3d224c9b64c6bf Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 09:30:19 +0100 Subject: [PATCH 21/61] refactor: KeyType entfernt --- DigitalData.Core.Security/RSADecryptor.cs | 3 --- DigitalData.Core.Security/RSAEncryptor.cs | 3 --- 2 files changed, 6 deletions(-) diff --git a/DigitalData.Core.Security/RSADecryptor.cs b/DigitalData.Core.Security/RSADecryptor.cs index 60bfc71..a527fe5 100644 --- a/DigitalData.Core.Security/RSADecryptor.cs +++ b/DigitalData.Core.Security/RSADecryptor.cs @@ -1,5 +1,4 @@ using DigitalData.Core.Abstractions.Security; -using DigitalData.Core.Security.DigitalData.Core.Security; using DigitalData.Core.Security.Extensions; using System.Security.Cryptography; @@ -32,8 +31,6 @@ namespace DigitalData.Core.Security protected override RSA RSA => lazyRSA.Value; - public override CryptKeyType KeyType => IsEncrypted ? CryptKeyType.EncryptedPrivate : CryptKeyType.Private; - public RSADecryptor() { _lazyEncryptor = new(() => new RSAEncryptor() diff --git a/DigitalData.Core.Security/RSAEncryptor.cs b/DigitalData.Core.Security/RSAEncryptor.cs index 36e6177..7783902 100644 --- a/DigitalData.Core.Security/RSAEncryptor.cs +++ b/DigitalData.Core.Security/RSAEncryptor.cs @@ -1,5 +1,4 @@ using DigitalData.Core.Abstractions.Security; -using DigitalData.Core.Security.DigitalData.Core.Security; using DigitalData.Core.Security.Extensions; namespace DigitalData.Core.Security @@ -16,8 +15,6 @@ namespace DigitalData.Core.Security } } - public override CryptKeyType KeyType => CryptKeyType.Public; - public byte[] Encrypt(byte[] data) => RSA.Encrypt(data, Padding); public string Encrypt(string data) => RSA.Encrypt(data.Base64ToByte(), Padding).BytesToString(); From d0dfd834b051ee67c134ef13761bfecce331611c Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 09:57:12 +0100 Subject: [PATCH 22/61] feat(Config): Verzeichnis erstellt und Params verschoben --- DigitalData.Core.Security/AsymCryptService.cs | 1 + DigitalData.Core.Security/{ => Config}/AsymCryptParams.cs | 2 +- DigitalData.Core.Security/{ => Config}/RSAFactoryParams.cs | 2 +- DigitalData.Core.Security/DIExtensions.cs | 1 + DigitalData.Core.Security/RSAFactory.cs | 1 + 5 files changed, 5 insertions(+), 2 deletions(-) rename DigitalData.Core.Security/{ => Config}/AsymCryptParams.cs (79%) rename DigitalData.Core.Security/{ => Config}/RSAFactoryParams.cs (96%) diff --git a/DigitalData.Core.Security/AsymCryptService.cs b/DigitalData.Core.Security/AsymCryptService.cs index d68561d..12ea349 100644 --- a/DigitalData.Core.Security/AsymCryptService.cs +++ b/DigitalData.Core.Security/AsymCryptService.cs @@ -1,4 +1,5 @@ using DigitalData.Core.Abstractions.Security; +using DigitalData.Core.Security.Config; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; diff --git a/DigitalData.Core.Security/AsymCryptParams.cs b/DigitalData.Core.Security/Config/AsymCryptParams.cs similarity index 79% rename from DigitalData.Core.Security/AsymCryptParams.cs rename to DigitalData.Core.Security/Config/AsymCryptParams.cs index dfe0991..85a460c 100644 --- a/DigitalData.Core.Security/AsymCryptParams.cs +++ b/DigitalData.Core.Security/Config/AsymCryptParams.cs @@ -1,4 +1,4 @@ -namespace DigitalData.Core.Security +namespace DigitalData.Core.Security.Config { public class AsymCryptParams : RSAFactoryParams { diff --git a/DigitalData.Core.Security/RSAFactoryParams.cs b/DigitalData.Core.Security/Config/RSAFactoryParams.cs similarity index 96% rename from DigitalData.Core.Security/RSAFactoryParams.cs rename to DigitalData.Core.Security/Config/RSAFactoryParams.cs index 6a093af..623da0c 100644 --- a/DigitalData.Core.Security/RSAFactoryParams.cs +++ b/DigitalData.Core.Security/Config/RSAFactoryParams.cs @@ -1,6 +1,6 @@ using System.Security.Cryptography; -namespace DigitalData.Core.Security +namespace DigitalData.Core.Security.Config { public class RSAFactoryParams { diff --git a/DigitalData.Core.Security/DIExtensions.cs b/DigitalData.Core.Security/DIExtensions.cs index 7b92f69..c12ee8a 100644 --- a/DigitalData.Core.Security/DIExtensions.cs +++ b/DigitalData.Core.Security/DIExtensions.cs @@ -1,4 +1,5 @@ using DigitalData.Core.Abstractions.Security; +using DigitalData.Core.Security.Config; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; diff --git a/DigitalData.Core.Security/RSAFactory.cs b/DigitalData.Core.Security/RSAFactory.cs index c403549..1539765 100644 --- a/DigitalData.Core.Security/RSAFactory.cs +++ b/DigitalData.Core.Security/RSAFactory.cs @@ -1,4 +1,5 @@ using DigitalData.Core.Abstractions.Security; +using DigitalData.Core.Security.Config; using Microsoft.Extensions.Options; using System.Security.Cryptography; From 6e4942c885d90e6ea83c7e82fbadf2a41b44bf52 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 09:58:42 +0100 Subject: [PATCH 23/61] feat(Config): Verzeichnis erstellt --- DigitalData.Core.Security/DigitalData.Core.Security.csproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DigitalData.Core.Security/DigitalData.Core.Security.csproj b/DigitalData.Core.Security/DigitalData.Core.Security.csproj index c198a40..7c301a2 100644 --- a/DigitalData.Core.Security/DigitalData.Core.Security.csproj +++ b/DigitalData.Core.Security/DigitalData.Core.Security.csproj @@ -15,4 +15,8 @@ + + + + From c38f7dcf72211cbe422dc0a95f37f04b344452b9 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 10:03:39 +0100 Subject: [PATCH 24/61] =?UTF-8?q?rektor(RSA):=20Umbenennung=20von=20dir=20?= =?UTF-8?q?in=20cryptographer=20und=20Verschiebung=20der=20zugeh=C3=B6rige?= =?UTF-8?q?n=20Klassen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DigitalData.Core.Security/AsymCryptService.cs | 1 + .../{ => Cryptographer}/RSACryptographer.cs | 4 ++-- .../{ => Cryptographer}/RSADecryptor.cs | 6 +++--- .../{ => Cryptographer}/RSAEncryptor.cs | 6 +++--- .../{ => Cryptographer}/RSAFactory.cs | 10 +++++----- DigitalData.Core.Security/DIExtensions.cs | 1 + .../DigitalData.Core.Security.csproj | 4 ---- 7 files changed, 15 insertions(+), 17 deletions(-) rename DigitalData.Core.Security/{ => Cryptographer}/RSACryptographer.cs (90%) rename DigitalData.Core.Security/{ => Cryptographer}/RSADecryptor.cs (95%) rename DigitalData.Core.Security/{ => Cryptographer}/RSAEncryptor.cs (87%) rename DigitalData.Core.Security/{ => Cryptographer}/RSAFactory.cs (92%) diff --git a/DigitalData.Core.Security/AsymCryptService.cs b/DigitalData.Core.Security/AsymCryptService.cs index 12ea349..cf42c91 100644 --- a/DigitalData.Core.Security/AsymCryptService.cs +++ b/DigitalData.Core.Security/AsymCryptService.cs @@ -1,5 +1,6 @@ using DigitalData.Core.Abstractions.Security; using DigitalData.Core.Security.Config; +using DigitalData.Core.Security.Cryptographer; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; diff --git a/DigitalData.Core.Security/RSACryptographer.cs b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs similarity index 90% rename from DigitalData.Core.Security/RSACryptographer.cs rename to DigitalData.Core.Security/Cryptographer/RSACryptographer.cs index 1b357bd..a128c62 100644 --- a/DigitalData.Core.Security/RSACryptographer.cs +++ b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs @@ -1,7 +1,7 @@ using DigitalData.Core.Abstractions.Security; using System.Security.Cryptography; -namespace DigitalData.Core.Security +namespace DigitalData.Core.Security.Cryptographer { public class RSACryptographer : IRSACryptographer { @@ -14,7 +14,7 @@ namespace DigitalData.Core.Security public string? Issuer { get; init; } public string? Audience { get; init; } - + internal RSACryptographer() { } } } \ No newline at end of file diff --git a/DigitalData.Core.Security/RSADecryptor.cs b/DigitalData.Core.Security/Cryptographer/RSADecryptor.cs similarity index 95% rename from DigitalData.Core.Security/RSADecryptor.cs rename to DigitalData.Core.Security/Cryptographer/RSADecryptor.cs index a527fe5..b1bf7b1 100644 --- a/DigitalData.Core.Security/RSADecryptor.cs +++ b/DigitalData.Core.Security/Cryptographer/RSADecryptor.cs @@ -2,7 +2,7 @@ using DigitalData.Core.Security.Extensions; using System.Security.Cryptography; -namespace DigitalData.Core.Security +namespace DigitalData.Core.Security.Cryptographer { public class RSADecryptor : RSACryptographer, IRSADecryptor, IRSACryptographer { @@ -31,7 +31,7 @@ namespace DigitalData.Core.Security protected override RSA RSA => lazyRSA.Value; - public RSADecryptor() + public RSADecryptor() { _lazyEncryptor = new(() => new RSAEncryptor() { @@ -50,7 +50,7 @@ namespace DigitalData.Core.Security return rsa; }); } - + public byte[] Decrypt(byte[] data) => RSA.Decrypt(data, Padding); public string Decrypt(string data) => RSA.Decrypt(data.Base64ToByte(), Padding).BytesToString(); diff --git a/DigitalData.Core.Security/RSAEncryptor.cs b/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs similarity index 87% rename from DigitalData.Core.Security/RSAEncryptor.cs rename to DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs index 7783902..2445b30 100644 --- a/DigitalData.Core.Security/RSAEncryptor.cs +++ b/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs @@ -1,13 +1,13 @@ using DigitalData.Core.Abstractions.Security; using DigitalData.Core.Security.Extensions; -namespace DigitalData.Core.Security +namespace DigitalData.Core.Security.Cryptographer { public class RSAEncryptor : RSACryptographer, IRSAEncryptor, IRSACryptographer { public override required string Pem - { - get => base.Pem; + { + get => base.Pem; init { RSA.ImportFromPem(base.Pem); diff --git a/DigitalData.Core.Security/RSAFactory.cs b/DigitalData.Core.Security/Cryptographer/RSAFactory.cs similarity index 92% rename from DigitalData.Core.Security/RSAFactory.cs rename to DigitalData.Core.Security/Cryptographer/RSAFactory.cs index 1539765..ebdc603 100644 --- a/DigitalData.Core.Security/RSAFactory.cs +++ b/DigitalData.Core.Security/Cryptographer/RSAFactory.cs @@ -3,7 +3,7 @@ using DigitalData.Core.Security.Config; using Microsoft.Extensions.Options; using System.Security.Cryptography; -namespace DigitalData.Core.Security +namespace DigitalData.Core.Security.Cryptographer { public class RSAFactory : IRSAFactory where TRSAFactoryParams : RSAFactoryParams { @@ -12,7 +12,7 @@ namespace DigitalData.Core.Security public static RSAFactory Static => LazyInstance.Value; protected readonly TRSAFactoryParams _params; - + public RSAFactory(IOptions options) => _params = options.Value; public string CreateRSAPrivateKeyPem(int? keySizeInBits = null) @@ -27,13 +27,13 @@ namespace DigitalData.Core.Security { password ??= _params.PbePassword; - var pbeParameters = (pbeEncryptionAlgorithm is null && hashAlgorithmName is null && iterationCount is null) + var pbeParameters = pbeEncryptionAlgorithm is null && hashAlgorithmName is null && iterationCount is null ? new PbeParameters( pbeEncryptionAlgorithm ?? _params.PbeEncryptionAlgorithm, hashAlgorithmName ?? _params.PbeHashAlgorithmName, iterationCount ?? _params.PbeIterationCount) : _params.PbeParameters; - + var encryptedPrivateKey = RSA.Create(keySizeInBits ?? _params.KeySizeInBits).ExportEncryptedPkcs8PrivateKey(password.AsSpan(), pbeParameters); var pemChars = PemEncoding.Write(_params.EncryptedPrivateKeyPemLabel, encryptedPrivateKey); @@ -47,7 +47,7 @@ namespace DigitalData.Core.Security (string Value, Version Version)? versionedPassword = null; - if(version is not null) + if (version is not null) { if (version != Secrets.Version) throw new InvalidOperationException($"The provided version {version} does not match the expected version {Secrets.Version}."); diff --git a/DigitalData.Core.Security/DIExtensions.cs b/DigitalData.Core.Security/DIExtensions.cs index c12ee8a..644e770 100644 --- a/DigitalData.Core.Security/DIExtensions.cs +++ b/DigitalData.Core.Security/DIExtensions.cs @@ -1,5 +1,6 @@ using DigitalData.Core.Abstractions.Security; using DigitalData.Core.Security.Config; +using DigitalData.Core.Security.Cryptographer; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; diff --git a/DigitalData.Core.Security/DigitalData.Core.Security.csproj b/DigitalData.Core.Security/DigitalData.Core.Security.csproj index 7c301a2..c198a40 100644 --- a/DigitalData.Core.Security/DigitalData.Core.Security.csproj +++ b/DigitalData.Core.Security/DigitalData.Core.Security.csproj @@ -15,8 +15,4 @@ - - - - From 8076efb9349c7f7d16cdf9195a9dfa86261f89ab Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 10:28:15 +0100 Subject: [PATCH 25/61] refactor(ReadOrCreateDirectory): Entfernt --- DigitalData.Core.Security/ReadOrCreateDirectory.cs | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 DigitalData.Core.Security/ReadOrCreateDirectory.cs diff --git a/DigitalData.Core.Security/ReadOrCreateDirectory.cs b/DigitalData.Core.Security/ReadOrCreateDirectory.cs deleted file mode 100644 index c53971e..0000000 --- a/DigitalData.Core.Security/ReadOrCreateDirectory.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace DigitalData.Core.Security -{ - public class ReadOrCreateDirectory - { - public required string Dir { get; init; } - - public IEnumerable ReadOrCreateFiles { get; init; } = new List(); - } -} \ No newline at end of file From 2e68a37944aee0ddfa24ce047393b13882e770b3 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 11:06:11 +0100 Subject: [PATCH 26/61] =?UTF-8?q?feat(HashAlgorithmNameConverter):=20Erste?= =?UTF-8?q?llt=20f=C3=BCr=20benutzerfreundlichere=20json=20de/serilization?= =?UTF-8?q?.=20=20-=20DI-Erweiterungsmethoden=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DigitalData.Core.Security/DIExtensions.cs | 12 ++++++++++++ .../HashAlgorithmNameConverter.cs | 13 +++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 DigitalData.Core.Security/HashAlgorithmNameConverter.cs diff --git a/DigitalData.Core.Security/DIExtensions.cs b/DigitalData.Core.Security/DIExtensions.cs index 644e770..1ecb854 100644 --- a/DigitalData.Core.Security/DIExtensions.cs +++ b/DigitalData.Core.Security/DIExtensions.cs @@ -5,11 +5,23 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; +using System.Text.Json; +using System.Text.Json.Serialization; namespace DigitalData.Core.Security { public static class DIExtensions { + public static JsonSerializerOptions TryAddCryptographerConverter(this JsonSerializerOptions options) + { + if (!options.Converters.OfType().Any()) + options.Converters.Add(new HashAlgorithmNameConverter()); + + if (!options.Converters.OfType().Any()) + options.Converters.Add(new JsonStringEnumConverter()); + return options; + } + private static IServiceCollection AddAsymCryptService(this IServiceCollection services) where TAsymCryptParams : AsymCryptParams { diff --git a/DigitalData.Core.Security/HashAlgorithmNameConverter.cs b/DigitalData.Core.Security/HashAlgorithmNameConverter.cs new file mode 100644 index 0000000..8fe7a53 --- /dev/null +++ b/DigitalData.Core.Security/HashAlgorithmNameConverter.cs @@ -0,0 +1,13 @@ +using System.Security.Cryptography; +using System.Text.Json.Serialization; +using System.Text.Json; + +namespace DigitalData.Core.Security +{ + public class HashAlgorithmNameConverter : JsonConverter + { + public override HashAlgorithmName Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => new(reader.GetString() ?? string.Empty); + + public override void Write(Utf8JsonWriter writer, HashAlgorithmName value, JsonSerializerOptions options) => writer.WriteStringValue(value.Name); + } +} \ No newline at end of file From 0d5bcedc01e21eab2a1f2f6e9686ebf239beb7ca Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 11:21:34 +0100 Subject: [PATCH 27/61] refactor(DIExtensions): Umbenennung von TryAddCryptographerConverter in AddCryptographerConverter --- DigitalData.Core.Security/DIExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DigitalData.Core.Security/DIExtensions.cs b/DigitalData.Core.Security/DIExtensions.cs index 1ecb854..652394d 100644 --- a/DigitalData.Core.Security/DIExtensions.cs +++ b/DigitalData.Core.Security/DIExtensions.cs @@ -12,7 +12,7 @@ namespace DigitalData.Core.Security { public static class DIExtensions { - public static JsonSerializerOptions TryAddCryptographerConverter(this JsonSerializerOptions options) + public static JsonSerializerOptions AddCryptographerConverter(this JsonSerializerOptions options) { if (!options.Converters.OfType().Any()) options.Converters.Add(new HashAlgorithmNameConverter()); From 5fd3fa2fc65b0d434be8ef27f5b936657a5d00a5 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 11:31:00 +0100 Subject: [PATCH 28/61] =?UTF-8?q?feat(AsymCryptParams):=20IRSADecryptor-Li?= =?UTF-8?q?ste=20und=20IRSAEncryptor-Liste=20hinzugef=C3=BCgt.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DigitalData.Core.Security/Config/AsymCryptParams.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/DigitalData.Core.Security/Config/AsymCryptParams.cs b/DigitalData.Core.Security/Config/AsymCryptParams.cs index 85a460c..0e167a8 100644 --- a/DigitalData.Core.Security/Config/AsymCryptParams.cs +++ b/DigitalData.Core.Security/Config/AsymCryptParams.cs @@ -1,7 +1,11 @@ -namespace DigitalData.Core.Security.Config +using DigitalData.Core.Abstractions.Security; + +namespace DigitalData.Core.Security.Config { public class AsymCryptParams : RSAFactoryParams { - public IEnumerable ReadOrCreateDirs { get; init; } = new List(); + public IEnumerable Decryptors { get; init; } = new List(); + + public IEnumerable Encryptors { get; init; } = new List(); } } \ No newline at end of file From e9d408a7177c9b27ea2c0dcdd2c57fe778425aaf Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 11:34:35 +0100 Subject: [PATCH 29/61] feat(AsymCryptParams): EncryptedPrivateKeyFileTag, PrivateKeyFileTag, PublicKeyFileTag und RSAKeyNameSeparator aus RSAFactoryParams verschoben. --- DigitalData.Core.Security/Config/AsymCryptParams.cs | 8 ++++++++ DigitalData.Core.Security/Config/RSAFactoryParams.cs | 8 -------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/DigitalData.Core.Security/Config/AsymCryptParams.cs b/DigitalData.Core.Security/Config/AsymCryptParams.cs index 0e167a8..2040fa8 100644 --- a/DigitalData.Core.Security/Config/AsymCryptParams.cs +++ b/DigitalData.Core.Security/Config/AsymCryptParams.cs @@ -4,6 +4,14 @@ namespace DigitalData.Core.Security.Config { public class AsymCryptParams : RSAFactoryParams { + public string EncryptedPrivateKeyFileTag { get; init; } = "enc-private"; + + public string PrivateKeyFileTag { get; init; } = "private"; + + public string PublicKeyFileTag { get; init; } = "public"; + + public string RSAKeyNameSeparator { get; init; } = "-_-"; + public IEnumerable Decryptors { get; init; } = new List(); public IEnumerable Encryptors { get; init; } = new List(); diff --git a/DigitalData.Core.Security/Config/RSAFactoryParams.cs b/DigitalData.Core.Security/Config/RSAFactoryParams.cs index 623da0c..b03c122 100644 --- a/DigitalData.Core.Security/Config/RSAFactoryParams.cs +++ b/DigitalData.Core.Security/Config/RSAFactoryParams.cs @@ -4,14 +4,6 @@ namespace DigitalData.Core.Security.Config { public class RSAFactoryParams { - public string EncryptedPrivateKeyFileTag { get; init; } = "enc-private"; - - public string PrivateKeyFileTag { get; init; } = "private"; - - public string PublicKeyFileTag { get; init; } = "public"; - - public string RSAKeyNameSeparator { get; init; } = "-_-"; - public int KeySizeInBits { get; init; } = 2048; public string PbePassword { internal get; init; } = Secrets.PBE_PASSWORD; From fa60147507593fc86ec55f62a86e541934c9b8a9 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 12:12:56 +0100 Subject: [PATCH 30/61] refactor(RSAFactoryParams): Implementierung von IJsonOnDeserialized anstelle von Lazy Initialization. --- DigitalData.Core.Security/Config/RSAFactoryParams.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/DigitalData.Core.Security/Config/RSAFactoryParams.cs b/DigitalData.Core.Security/Config/RSAFactoryParams.cs index b03c122..7b1bd54 100644 --- a/DigitalData.Core.Security/Config/RSAFactoryParams.cs +++ b/DigitalData.Core.Security/Config/RSAFactoryParams.cs @@ -1,8 +1,9 @@ using System.Security.Cryptography; +using System.Text.Json.Serialization; namespace DigitalData.Core.Security.Config { - public class RSAFactoryParams + public class RSAFactoryParams : IJsonOnDeserialized { public int KeySizeInBits { get; init; } = 2048; @@ -16,11 +17,11 @@ namespace DigitalData.Core.Security.Config public string EncryptedPrivateKeyPemLabel { get; init; } = "ENCRYPTED PRIVATE KEY"; - private readonly Lazy _lazyPbeParameters; + private PbeParameters? _pbeParameters; - public PbeParameters PbeParameters => _lazyPbeParameters.Value; + [JsonIgnore] + public PbeParameters PbeParameters => _pbeParameters!; - public RSAFactoryParams() - => _lazyPbeParameters = new(() => new PbeParameters(PbeEncryptionAlgorithm, PbeHashAlgorithmName, PbeIterationCount)); + public void OnDeserialized() => _pbeParameters = new PbeParameters(PbeEncryptionAlgorithm, PbeHashAlgorithmName, PbeIterationCount); } } \ No newline at end of file From b8fb45d4a38057a2cc8b0eb2e13f246f6d2f95a4 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 13:17:23 +0100 Subject: [PATCH 31/61] =?UTF-8?q?feat(AsymCryptService):=20Decryptors=20un?= =?UTF-8?q?d=20Encryptors=20Getter=20hinzugef=C3=BCgt.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DigitalData.Core.Security/AsymCryptService.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DigitalData.Core.Security/AsymCryptService.cs b/DigitalData.Core.Security/AsymCryptService.cs index cf42c91..3059fce 100644 --- a/DigitalData.Core.Security/AsymCryptService.cs +++ b/DigitalData.Core.Security/AsymCryptService.cs @@ -8,6 +8,10 @@ namespace DigitalData.Core.Security { public class AsymCryptService : RSAFactory, IAsymCryptService, IRSAFactory where TAsymCryptParams : AsymCryptParams { + public IEnumerable Decryptors => _params.Decryptors; + + public IEnumerable Encryptors => _params.Encryptors; + private readonly Dictionary _decryptors; public IRSADecryptor this[string key] { get => _decryptors[key]; set => _decryptors[key] = value; } From 35e2fef046e151877a1778e66fc044ec9d0dd53e Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 13:37:34 +0100 Subject: [PATCH 32/61] =?UTF-8?q?feat(RSACryptographerList):=20Erstellt,?= =?UTF-8?q?=20um=20die=20Cryptographer-Liste=20sowohl=20als=20W=C3=B6rterb?= =?UTF-8?q?uch=20als=20auch=20als=20IEnumerable=20zu=20verwenden?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Cryptographer/RSACryptographerList.cs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 DigitalData.Core.Security/Cryptographer/RSACryptographerList.cs diff --git a/DigitalData.Core.Security/Cryptographer/RSACryptographerList.cs b/DigitalData.Core.Security/Cryptographer/RSACryptographerList.cs new file mode 100644 index 0000000..e4c4272 --- /dev/null +++ b/DigitalData.Core.Security/Cryptographer/RSACryptographerList.cs @@ -0,0 +1,24 @@ +using DigitalData.Core.Abstractions.Security; +using System.Collections; + +namespace DigitalData.Core.Security.Cryptographer +{ + public class RSACryptographerList : IEnumerable where TRSACryptographer : IRSACryptographer + { + private readonly Func _keyGenerator; + + private readonly IEnumerable _cryptographers; + + internal RSACryptographerList(Func keyGenerator, IEnumerable cryptographers) + { + _keyGenerator = keyGenerator; + _cryptographers = cryptographers; + } + + public TRSACryptographer? this[string key] => _cryptographers.SingleOrDefault(crypt => _keyGenerator(crypt) == key); + + public IEnumerator GetEnumerator() => _cryptographers.GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + } +} \ No newline at end of file From c96af25e2309592896d114322491bc1d8e2007c0 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 14:26:20 +0100 Subject: [PATCH 33/61] feat(CryptographerExtensions): Erstellt Erweiterungen zum Suchen und Erstellen von RSACryptographerList. --- .../Cryptographer/CryptographerExtensions.cs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs diff --git a/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs b/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs new file mode 100644 index 0000000..4452007 --- /dev/null +++ b/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs @@ -0,0 +1,29 @@ +namespace DigitalData.Core.Security.Cryptographer +{ + public static class CryptographerExtensions + { + public static IEnumerable GetByIssuer(this IEnumerable cryptographers, string issuer) where TRSACryptographer: RSACryptographer + => cryptographers.Where(c => c.Issuer == issuer); + + public static IEnumerable GetByAudience(this IEnumerable cryptographers, string audience) where TRSACryptographer : RSACryptographer + => cryptographers.Where(c => c.Audience == audience); + + public static TRSACryptographer Get(this IEnumerable cryptographers, string issuer, string audience) where TRSACryptographer : RSACryptographer + => cryptographers.Where(c => c.Issuer == issuer && c.Audience == audience).SingleOrDefault() + ?? throw new InvalidOperationException($"No {cryptographers.GetTypeName()} found with Issuer: {issuer} and Audience: {audience}"); + + public static bool TryGet(this IEnumerable cryptographers, string issuer, string audience, out TRSACryptographer? cryptographer) where TRSACryptographer : RSACryptographer + { + cryptographer = cryptographers.Where(c => c.Issuer == issuer && c.Audience == audience).SingleOrDefault(); + return cryptographer is not null; + } + + public static RSACryptographerList ToCryptographerList(this IEnumerable cryptographers, Func keyGenerator) where TRSACryptographer : RSACryptographer + => new(keyGenerator: keyGenerator, cryptographers: cryptographers); + + private static string GetTypeName(this IEnumerable cryptographers) where TRSACryptographer : RSACryptographer + => typeof(TRSACryptographer).GetType().Name.TrimStart(InterfaceIdentifierChar); + + private static readonly char InterfaceIdentifierChar = 'I'; + } +} \ No newline at end of file From 738005f5dc84c81ae22446b717a4de89081ee703 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 14:33:24 +0100 Subject: [PATCH 34/61] feat(RSACryptographerList): Die Ausgabe der Indexer-Methode ist nicht null und wirft eine Ausnahme, wenn sie nicht gefunden wird. --- .../Cryptographer/CryptographerExtensions.cs | 7 +------ .../Cryptographer/RSACryptographerList.cs | 4 +++- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs b/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs index 4452007..72f58e0 100644 --- a/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs +++ b/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs @@ -10,7 +10,7 @@ public static TRSACryptographer Get(this IEnumerable cryptographers, string issuer, string audience) where TRSACryptographer : RSACryptographer => cryptographers.Where(c => c.Issuer == issuer && c.Audience == audience).SingleOrDefault() - ?? throw new InvalidOperationException($"No {cryptographers.GetTypeName()} found with Issuer: {issuer} and Audience: {audience}"); + ?? throw new InvalidOperationException($"No {typeof(TRSACryptographer).GetType().Name.TrimStart('I')} found with Issuer: {issuer} and Audience: {audience}."); public static bool TryGet(this IEnumerable cryptographers, string issuer, string audience, out TRSACryptographer? cryptographer) where TRSACryptographer : RSACryptographer { @@ -20,10 +20,5 @@ public static RSACryptographerList ToCryptographerList(this IEnumerable cryptographers, Func keyGenerator) where TRSACryptographer : RSACryptographer => new(keyGenerator: keyGenerator, cryptographers: cryptographers); - - private static string GetTypeName(this IEnumerable cryptographers) where TRSACryptographer : RSACryptographer - => typeof(TRSACryptographer).GetType().Name.TrimStart(InterfaceIdentifierChar); - - private static readonly char InterfaceIdentifierChar = 'I'; } } \ No newline at end of file diff --git a/DigitalData.Core.Security/Cryptographer/RSACryptographerList.cs b/DigitalData.Core.Security/Cryptographer/RSACryptographerList.cs index e4c4272..f7ab7a7 100644 --- a/DigitalData.Core.Security/Cryptographer/RSACryptographerList.cs +++ b/DigitalData.Core.Security/Cryptographer/RSACryptographerList.cs @@ -15,7 +15,9 @@ namespace DigitalData.Core.Security.Cryptographer _cryptographers = cryptographers; } - public TRSACryptographer? this[string key] => _cryptographers.SingleOrDefault(crypt => _keyGenerator(crypt) == key); + public TRSACryptographer this[string key] + => _cryptographers.SingleOrDefault(crypt => _keyGenerator(crypt) == key) + ?? throw new InvalidOperationException($"No {typeof(TRSACryptographer).GetType().Name.TrimStart('I')} found with Key: {key}."); public IEnumerator GetEnumerator() => _cryptographers.GetEnumerator(); From 016d8bdcf2a07eadc4a07c945cae535289acd5fe Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 14:36:28 +0100 Subject: [PATCH 35/61] =?UTF-8?q?feat(RSACryptographerList):=20Hinzuf?= =?UTF-8?q?=C3=BCgen=20der=20Methode=20try=20get=20mit=20dem=20Wort=20out-?= =?UTF-8?q?key?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Cryptographer/RSACryptographerList.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/DigitalData.Core.Security/Cryptographer/RSACryptographerList.cs b/DigitalData.Core.Security/Cryptographer/RSACryptographerList.cs index f7ab7a7..6bfada7 100644 --- a/DigitalData.Core.Security/Cryptographer/RSACryptographerList.cs +++ b/DigitalData.Core.Security/Cryptographer/RSACryptographerList.cs @@ -19,6 +19,12 @@ namespace DigitalData.Core.Security.Cryptographer => _cryptographers.SingleOrDefault(crypt => _keyGenerator(crypt) == key) ?? throw new InvalidOperationException($"No {typeof(TRSACryptographer).GetType().Name.TrimStart('I')} found with Key: {key}."); + public bool TryGet(string key, out TRSACryptographer? cryptographer) + { + cryptographer = _cryptographers.SingleOrDefault(crypt => _keyGenerator(crypt) == key); + return cryptographer is not null; + } + public IEnumerator GetEnumerator() => _cryptographers.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); From a69f610ef4d4f5dd0bd040956879a02022dcd603 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 14:38:32 +0100 Subject: [PATCH 36/61] feat(CryptographerExtensions): Abfrage in SingleOrDefault verschieben --- .../Cryptographer/CryptographerExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs b/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs index 72f58e0..5c892c5 100644 --- a/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs +++ b/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs @@ -14,7 +14,7 @@ public static bool TryGet(this IEnumerable cryptographers, string issuer, string audience, out TRSACryptographer? cryptographer) where TRSACryptographer : RSACryptographer { - cryptographer = cryptographers.Where(c => c.Issuer == issuer && c.Audience == audience).SingleOrDefault(); + cryptographer = cryptographers.SingleOrDefault(c => c.Issuer == issuer && c.Audience == audience); return cryptographer is not null; } From b8a4a1f2b5bd76ad60335e4f48b2ca3604dec4eb Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 14:50:05 +0100 Subject: [PATCH 37/61] =?UTF-8?q?refactor(IRSACryptographer):=20Issuer=20u?= =?UTF-8?q?nd=20Audience=20Identifier=20String-Eigenschaften=20hinzugef?= =?UTF-8?q?=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DigitalData.Core.Abstractions/Security/IRSACryptographer.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs b/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs index acf7320..406efa8 100644 --- a/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs +++ b/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs @@ -7,5 +7,9 @@ namespace DigitalData.Core.Abstractions.Security public string Pem { get; init; } public RSAEncryptionPadding Padding { get; init; } + + public string? Issuer { get; init; } + + public string? Audience { get; init; } } } \ No newline at end of file From baf1f5e045fc467f087ff7bd686d55083f98bb68 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 14:58:44 +0100 Subject: [PATCH 38/61] =?UTF-8?q?refactor(CryptographerExtensions):=20Aktu?= =?UTF-8?q?alisiert,=20um=20IRSACryptographer=20anstelle=20von=20RSACrypto?= =?UTF-8?q?grapher=20zu=20verwenden,=20um=20die=20Abstraktion=20zu=20erh?= =?UTF-8?q?=C3=B6hen.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Cryptographer/CryptographerExtensions.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs b/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs index 5c892c5..47ce618 100644 --- a/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs +++ b/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs @@ -1,24 +1,26 @@ -namespace DigitalData.Core.Security.Cryptographer +using DigitalData.Core.Abstractions.Security; + +namespace DigitalData.Core.Security.Cryptographer { public static class CryptographerExtensions { - public static IEnumerable GetByIssuer(this IEnumerable cryptographers, string issuer) where TRSACryptographer: RSACryptographer + public static IEnumerable GetByIssuer(this IEnumerable cryptographers, string issuer) where TRSACryptographer: IRSACryptographer => cryptographers.Where(c => c.Issuer == issuer); - public static IEnumerable GetByAudience(this IEnumerable cryptographers, string audience) where TRSACryptographer : RSACryptographer + public static IEnumerable GetByAudience(this IEnumerable cryptographers, string audience) where TRSACryptographer : IRSACryptographer => cryptographers.Where(c => c.Audience == audience); - public static TRSACryptographer Get(this IEnumerable cryptographers, string issuer, string audience) where TRSACryptographer : RSACryptographer + public static TRSACryptographer Get(this IEnumerable cryptographers, string issuer, string audience) where TRSACryptographer : IRSACryptographer => cryptographers.Where(c => c.Issuer == issuer && c.Audience == audience).SingleOrDefault() ?? throw new InvalidOperationException($"No {typeof(TRSACryptographer).GetType().Name.TrimStart('I')} found with Issuer: {issuer} and Audience: {audience}."); - public static bool TryGet(this IEnumerable cryptographers, string issuer, string audience, out TRSACryptographer? cryptographer) where TRSACryptographer : RSACryptographer + public static bool TryGet(this IEnumerable cryptographers, string issuer, string audience, out TRSACryptographer? cryptographer) where TRSACryptographer : IRSACryptographer { cryptographer = cryptographers.SingleOrDefault(c => c.Issuer == issuer && c.Audience == audience); return cryptographer is not null; } - public static RSACryptographerList ToCryptographerList(this IEnumerable cryptographers, Func keyGenerator) where TRSACryptographer : RSACryptographer + public static RSACryptographerList ToCryptographerList(this IEnumerable cryptographers, Func keyGenerator) where TRSACryptographer : IRSACryptographer => new(keyGenerator: keyGenerator, cryptographers: cryptographers); } } \ No newline at end of file From 2f0c6a905a6dc8e1aa037b90c19aef0deaf5aa4f Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 15:03:28 +0100 Subject: [PATCH 39/61] =?UTF-8?q?chore:=20Hinzugef=C3=BCgtes=20ToDo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Cryptographer/CryptographerExtensions.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs b/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs index 47ce618..3c24ffa 100644 --- a/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs +++ b/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs @@ -2,6 +2,7 @@ namespace DigitalData.Core.Security.Cryptographer { + //TODO: Create seperated extensions project public static class CryptographerExtensions { public static IEnumerable GetByIssuer(this IEnumerable cryptographers, string issuer) where TRSACryptographer: IRSACryptographer From b02f93b38dbae945569b95377c81f4f3ba8c9ba4 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 15:19:44 +0100 Subject: [PATCH 40/61] refactor(RSACryptographerList): entfernt --- .../Cryptographer/CryptographerExtensions.cs | 3 -- .../Cryptographer/RSACryptographerList.cs | 32 ------------------- 2 files changed, 35 deletions(-) delete mode 100644 DigitalData.Core.Security/Cryptographer/RSACryptographerList.cs diff --git a/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs b/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs index 3c24ffa..d0598a0 100644 --- a/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs +++ b/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs @@ -20,8 +20,5 @@ namespace DigitalData.Core.Security.Cryptographer cryptographer = cryptographers.SingleOrDefault(c => c.Issuer == issuer && c.Audience == audience); return cryptographer is not null; } - - public static RSACryptographerList ToCryptographerList(this IEnumerable cryptographers, Func keyGenerator) where TRSACryptographer : IRSACryptographer - => new(keyGenerator: keyGenerator, cryptographers: cryptographers); } } \ No newline at end of file diff --git a/DigitalData.Core.Security/Cryptographer/RSACryptographerList.cs b/DigitalData.Core.Security/Cryptographer/RSACryptographerList.cs deleted file mode 100644 index 6bfada7..0000000 --- a/DigitalData.Core.Security/Cryptographer/RSACryptographerList.cs +++ /dev/null @@ -1,32 +0,0 @@ -using DigitalData.Core.Abstractions.Security; -using System.Collections; - -namespace DigitalData.Core.Security.Cryptographer -{ - public class RSACryptographerList : IEnumerable where TRSACryptographer : IRSACryptographer - { - private readonly Func _keyGenerator; - - private readonly IEnumerable _cryptographers; - - internal RSACryptographerList(Func keyGenerator, IEnumerable cryptographers) - { - _keyGenerator = keyGenerator; - _cryptographers = cryptographers; - } - - public TRSACryptographer this[string key] - => _cryptographers.SingleOrDefault(crypt => _keyGenerator(crypt) == key) - ?? throw new InvalidOperationException($"No {typeof(TRSACryptographer).GetType().Name.TrimStart('I')} found with Key: {key}."); - - public bool TryGet(string key, out TRSACryptographer? cryptographer) - { - cryptographer = _cryptographers.SingleOrDefault(crypt => _keyGenerator(crypt) == key); - return cryptographer is not null; - } - - public IEnumerator GetEnumerator() => _cryptographers.GetEnumerator(); - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - } -} \ No newline at end of file From 8003cffb9bad24047ec81629cd47865bc0bf343f Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 15:20:56 +0100 Subject: [PATCH 41/61] refactor(CryptographerExtensions): In die Abstraktionsschicht verschieben --- .../Security}/CryptographerExtensions.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) rename {DigitalData.Core.Security/Cryptographer => DigitalData.Core.Abstractions/Security}/CryptographerExtensions.cs (90%) diff --git a/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs b/DigitalData.Core.Abstractions/Security/CryptographerExtensions.cs similarity index 90% rename from DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs rename to DigitalData.Core.Abstractions/Security/CryptographerExtensions.cs index d0598a0..2301e78 100644 --- a/DigitalData.Core.Security/Cryptographer/CryptographerExtensions.cs +++ b/DigitalData.Core.Abstractions/Security/CryptographerExtensions.cs @@ -1,8 +1,5 @@ -using DigitalData.Core.Abstractions.Security; - -namespace DigitalData.Core.Security.Cryptographer +namespace DigitalData.Core.Abstractions.Security { - //TODO: Create seperated extensions project public static class CryptographerExtensions { public static IEnumerable GetByIssuer(this IEnumerable cryptographers, string issuer) where TRSACryptographer: IRSACryptographer From 6f520732dd89e6e89397e10de912404d31d0dd6d Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 15:22:23 +0100 Subject: [PATCH 42/61] =?UTF-8?q?refactor(AsymCryptService):=20Entschl?= =?UTF-8?q?=C3=BCsselungsw=C3=B6rterbuch=20entfernt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DigitalData.Core.Security/AsymCryptService.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/DigitalData.Core.Security/AsymCryptService.cs b/DigitalData.Core.Security/AsymCryptService.cs index 3059fce..cf6f008 100644 --- a/DigitalData.Core.Security/AsymCryptService.cs +++ b/DigitalData.Core.Security/AsymCryptService.cs @@ -12,16 +12,9 @@ namespace DigitalData.Core.Security public IEnumerable Encryptors => _params.Encryptors; - private readonly Dictionary _decryptors; - - public IRSADecryptor this[string key] { get => _decryptors[key]; set => _decryptors[key] = value; } - public AsymCryptService(IOptions options, ILogger>? logger = null) : base(options) { - _decryptors = new(); logger?.LogInformation("Core.Secrets version: {Version}, Created on: {CreationDate}.", Secrets.Version, Secrets.CreationDate.ToString("dd.MM.yyyy")); } - - public bool TryGetRSADecryptor(string key, out IRSADecryptor? decryptor) => _decryptors.TryGetValue(key, out decryptor); } } \ No newline at end of file From b3568216a063e1cc40d9c0d300ac23d9dafdd47e Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 15:47:46 +0100 Subject: [PATCH 43/61] =?UTF-8?q?refactor(IAsymCryptService):=20Indexer=20?= =?UTF-8?q?entfernt=20und=20Decryptors=20und=20Encryptors=20getter=20Metho?= =?UTF-8?q?den=20hinzugef=C3=BCgt.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DigitalData.Core.Abstractions/Security/IAsymCryptService.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DigitalData.Core.Abstractions/Security/IAsymCryptService.cs b/DigitalData.Core.Abstractions/Security/IAsymCryptService.cs index 9e95d14..81088ee 100644 --- a/DigitalData.Core.Abstractions/Security/IAsymCryptService.cs +++ b/DigitalData.Core.Abstractions/Security/IAsymCryptService.cs @@ -1,9 +1,9 @@ namespace DigitalData.Core.Abstractions.Security { public interface IAsymCryptService : IRSAFactory - { - IRSADecryptor this[string key] { get; } + { + public IEnumerable Decryptors { get; } - bool TryGetRSADecryptor(string key, out IRSADecryptor? decryptor); + public IEnumerable Encryptors { get; } } } \ No newline at end of file From 8787c049170eb805494b5abca71b6730204e18a3 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 15:50:53 +0100 Subject: [PATCH 44/61] =?UTF-8?q?refactor(AsymCryptParams):=20unn=C3=B6tig?= =?UTF-8?q?e=20Eigenschaften=20entfernt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DigitalData.Core.Security/Config/AsymCryptParams.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/DigitalData.Core.Security/Config/AsymCryptParams.cs b/DigitalData.Core.Security/Config/AsymCryptParams.cs index 2040fa8..0e167a8 100644 --- a/DigitalData.Core.Security/Config/AsymCryptParams.cs +++ b/DigitalData.Core.Security/Config/AsymCryptParams.cs @@ -4,14 +4,6 @@ namespace DigitalData.Core.Security.Config { public class AsymCryptParams : RSAFactoryParams { - public string EncryptedPrivateKeyFileTag { get; init; } = "enc-private"; - - public string PrivateKeyFileTag { get; init; } = "private"; - - public string PublicKeyFileTag { get; init; } = "public"; - - public string RSAKeyNameSeparator { get; init; } = "-_-"; - public IEnumerable Decryptors { get; init; } = new List(); public IEnumerable Encryptors { get; init; } = new List(); From 16565eca4d0d92182306e72081c73caa19f944c7 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 20:07:17 +0100 Subject: [PATCH 45/61] =?UTF-8?q?refactor(RSACryptographer):=20Entfernte?= =?UTF-8?q?=20nullbare=20Eigenschaft=20von=20Issuer=20und=20Audience.=20?= =?UTF-8?q?=20-=20Schnittstelle=20aktualisiert=20=20-=20standardm=C3=A4?= =?UTF-8?q?=C3=9Fig=20als=20leerer=20String=20zugewiesen.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Security/IRSACryptographer.cs | 4 +- .../Cryptographer/RSACryptographer.cs | 46 +++++++++++++++++-- .../Cryptographer/RSAEncryptor.cs | 4 +- 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs b/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs index 406efa8..9bbeb98 100644 --- a/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs +++ b/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs @@ -8,8 +8,8 @@ namespace DigitalData.Core.Abstractions.Security public RSAEncryptionPadding Padding { get; init; } - public string? Issuer { get; init; } + public string Issuer { get; init; } - public string? Audience { get; init; } + public string Audience { get; init; } } } \ No newline at end of file diff --git a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs index a128c62..3e08d47 100644 --- a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs +++ b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs @@ -1,20 +1,58 @@ using DigitalData.Core.Abstractions.Security; using System.Security.Cryptography; +using System.Text.Json.Serialization; namespace DigitalData.Core.Security.Cryptographer { - public class RSACryptographer : IRSACryptographer + public class RSACryptographer : IRSACryptographer, IJsonOnDeserialized { - public required virtual string Pem { get; init; } + private string? _pem; + + private string? _pemPath; + + public virtual string Pem + { + get => _pem!; + init + { + ValidatePemInit(); + _pem = value; + } + } + + public string? PemPath + { + get => _pemPath; + init + { + _pemPath = value; + if (value is null) + return; + ValidatePemInit(); + _pem = File.ReadAllText(value); + } + } public RSAEncryptionPadding Padding { get; init; } = RSAEncryptionPadding.OaepSHA256; protected virtual RSA RSA { get; } = RSA.Create(); - public string? Issuer { get; init; } + public string Issuer { get; init; } = string.Empty; - public string? Audience { get; init; } + public string Audience { get; init; } = string.Empty; internal RSACryptographer() { } + + public void OnDeserialized() + { + if (Pem is null) + throw new InvalidOperationException($"Pem must be initialized. Issuer: {Issuer} and Audience: {Audience}"); + } + + private void ValidatePemInit() + { + if (_pem is not null) + throw new InvalidOperationException($"Pem can only be initilized once. Remove one of the Pem or Pem file initilizations. Issuer: {Issuer} and Audience: {Audience}"); + } } } \ No newline at end of file diff --git a/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs b/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs index 2445b30..055a6bc 100644 --- a/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs +++ b/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs @@ -5,7 +5,7 @@ namespace DigitalData.Core.Security.Cryptographer { public class RSAEncryptor : RSACryptographer, IRSAEncryptor, IRSACryptographer { - public override required string Pem + public override string Pem { get => base.Pem; init @@ -14,7 +14,7 @@ namespace DigitalData.Core.Security.Cryptographer base.Pem = value; } } - + public byte[] Encrypt(byte[] data) => RSA.Encrypt(data, Padding); public string Encrypt(string data) => RSA.Encrypt(data.Base64ToByte(), Padding).BytesToString(); From 600d17ef40a1ed5092ba3bde0c22c03f825ae1fb Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 23:08:13 +0100 Subject: [PATCH 46/61] Revert "refactor(RSACryptographer): Entfernte nullbare Eigenschaft von Issuer und Audience." This reverts commit 16565eca4d0d92182306e72081c73caa19f944c7. --- .../Security/IRSACryptographer.cs | 4 +- .../Cryptographer/RSACryptographer.cs | 46 ++----------------- .../Cryptographer/RSAEncryptor.cs | 4 +- 3 files changed, 8 insertions(+), 46 deletions(-) diff --git a/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs b/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs index 9bbeb98..406efa8 100644 --- a/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs +++ b/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs @@ -8,8 +8,8 @@ namespace DigitalData.Core.Abstractions.Security public RSAEncryptionPadding Padding { get; init; } - public string Issuer { get; init; } + public string? Issuer { get; init; } - public string Audience { get; init; } + public string? Audience { get; init; } } } \ No newline at end of file diff --git a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs index 3e08d47..a128c62 100644 --- a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs +++ b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs @@ -1,58 +1,20 @@ using DigitalData.Core.Abstractions.Security; using System.Security.Cryptography; -using System.Text.Json.Serialization; namespace DigitalData.Core.Security.Cryptographer { - public class RSACryptographer : IRSACryptographer, IJsonOnDeserialized + public class RSACryptographer : IRSACryptographer { - private string? _pem; - - private string? _pemPath; - - public virtual string Pem - { - get => _pem!; - init - { - ValidatePemInit(); - _pem = value; - } - } - - public string? PemPath - { - get => _pemPath; - init - { - _pemPath = value; - if (value is null) - return; - ValidatePemInit(); - _pem = File.ReadAllText(value); - } - } + public required virtual string Pem { get; init; } public RSAEncryptionPadding Padding { get; init; } = RSAEncryptionPadding.OaepSHA256; protected virtual RSA RSA { get; } = RSA.Create(); - public string Issuer { get; init; } = string.Empty; + public string? Issuer { get; init; } - public string Audience { get; init; } = string.Empty; + public string? Audience { get; init; } internal RSACryptographer() { } - - public void OnDeserialized() - { - if (Pem is null) - throw new InvalidOperationException($"Pem must be initialized. Issuer: {Issuer} and Audience: {Audience}"); - } - - private void ValidatePemInit() - { - if (_pem is not null) - throw new InvalidOperationException($"Pem can only be initilized once. Remove one of the Pem or Pem file initilizations. Issuer: {Issuer} and Audience: {Audience}"); - } } } \ No newline at end of file diff --git a/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs b/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs index 055a6bc..2445b30 100644 --- a/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs +++ b/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs @@ -5,7 +5,7 @@ namespace DigitalData.Core.Security.Cryptographer { public class RSAEncryptor : RSACryptographer, IRSAEncryptor, IRSACryptographer { - public override string Pem + public override required string Pem { get => base.Pem; init @@ -14,7 +14,7 @@ namespace DigitalData.Core.Security.Cryptographer base.Pem = value; } } - + public byte[] Encrypt(byte[] data) => RSA.Encrypt(data, Padding); public string Encrypt(string data) => RSA.Encrypt(data.Base64ToByte(), Padding).BytesToString(); From 0ff89b4906b1ccc5c91d6619abd8dd209314efb4 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Thu, 5 Dec 2024 23:18:19 +0100 Subject: [PATCH 47/61] Reapply "refactor(RSACryptographer): Entfernte nullbare Eigenschaft von Issuer und Audience." This reverts commit 600d17ef40a1ed5092ba3bde0c22c03f825ae1fb. --- .../Security/IRSACryptographer.cs | 4 +- .../Cryptographer/RSACryptographer.cs | 46 +++++++++++++++++-- .../Cryptographer/RSAEncryptor.cs | 4 +- 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs b/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs index 406efa8..9bbeb98 100644 --- a/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs +++ b/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs @@ -8,8 +8,8 @@ namespace DigitalData.Core.Abstractions.Security public RSAEncryptionPadding Padding { get; init; } - public string? Issuer { get; init; } + public string Issuer { get; init; } - public string? Audience { get; init; } + public string Audience { get; init; } } } \ No newline at end of file diff --git a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs index a128c62..3e08d47 100644 --- a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs +++ b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs @@ -1,20 +1,58 @@ using DigitalData.Core.Abstractions.Security; using System.Security.Cryptography; +using System.Text.Json.Serialization; namespace DigitalData.Core.Security.Cryptographer { - public class RSACryptographer : IRSACryptographer + public class RSACryptographer : IRSACryptographer, IJsonOnDeserialized { - public required virtual string Pem { get; init; } + private string? _pem; + + private string? _pemPath; + + public virtual string Pem + { + get => _pem!; + init + { + ValidatePemInit(); + _pem = value; + } + } + + public string? PemPath + { + get => _pemPath; + init + { + _pemPath = value; + if (value is null) + return; + ValidatePemInit(); + _pem = File.ReadAllText(value); + } + } public RSAEncryptionPadding Padding { get; init; } = RSAEncryptionPadding.OaepSHA256; protected virtual RSA RSA { get; } = RSA.Create(); - public string? Issuer { get; init; } + public string Issuer { get; init; } = string.Empty; - public string? Audience { get; init; } + public string Audience { get; init; } = string.Empty; internal RSACryptographer() { } + + public void OnDeserialized() + { + if (Pem is null) + throw new InvalidOperationException($"Pem must be initialized. Issuer: {Issuer} and Audience: {Audience}"); + } + + private void ValidatePemInit() + { + if (_pem is not null) + throw new InvalidOperationException($"Pem can only be initilized once. Remove one of the Pem or Pem file initilizations. Issuer: {Issuer} and Audience: {Audience}"); + } } } \ No newline at end of file diff --git a/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs b/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs index 2445b30..055a6bc 100644 --- a/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs +++ b/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs @@ -5,7 +5,7 @@ namespace DigitalData.Core.Security.Cryptographer { public class RSAEncryptor : RSACryptographer, IRSAEncryptor, IRSACryptographer { - public override required string Pem + public override string Pem { get => base.Pem; init @@ -14,7 +14,7 @@ namespace DigitalData.Core.Security.Cryptographer base.Pem = value; } } - + public byte[] Encrypt(byte[] data) => RSA.Encrypt(data, Padding); public string Encrypt(string data) => RSA.Encrypt(data.Base64ToByte(), Padding).BytesToString(); From bea57a25e89ea1ea6b3a1a7ce88e96bc976fc544 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Fri, 6 Dec 2024 15:12:21 +0100 Subject: [PATCH 48/61] =?UTF-8?q?feat(RSACryptographer)=20Init-Methode=20z?= =?UTF-8?q?ur=20Verwaltung=20des=20pem-Importprozesses=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Security/IRSACryptographer.cs | 5 ++- .../Cryptographer/RSACryptographer.cs | 38 ++++++------------- 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs b/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs index 9bbeb98..4472344 100644 --- a/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs +++ b/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs @@ -1,8 +1,9 @@ using System.Security.Cryptography; +using System.Text.Json.Serialization; namespace DigitalData.Core.Abstractions.Security { - public interface IRSACryptographer + public interface IRSACryptographer : IJsonOnDeserialized { public string Pem { get; init; } @@ -11,5 +12,7 @@ namespace DigitalData.Core.Abstractions.Security public string Issuer { get; init; } public string Audience { get; init; } + + public void Init(); } } \ No newline at end of file diff --git a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs index 3e08d47..06e53be 100644 --- a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs +++ b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs @@ -10,28 +10,9 @@ namespace DigitalData.Core.Security.Cryptographer private string? _pemPath; - public virtual string Pem - { - get => _pem!; - init - { - ValidatePemInit(); - _pem = value; - } - } + public virtual string Pem { get => _pem; init => _pem = value; } - public string? PemPath - { - get => _pemPath; - init - { - _pemPath = value; - if (value is null) - return; - ValidatePemInit(); - _pem = File.ReadAllText(value); - } - } + public string? PemPath { get => _pemPath; init => _pemPath = value; } public RSAEncryptionPadding Padding { get; init; } = RSAEncryptionPadding.OaepSHA256; @@ -45,14 +26,19 @@ namespace DigitalData.Core.Security.Cryptographer public void OnDeserialized() { - if (Pem is null) - throw new InvalidOperationException($"Pem must be initialized. Issuer: {Issuer} and Audience: {Audience}"); + Init(); } - private void ValidatePemInit() + // TODO: make file read asynchronous, consider multiple routing + public virtual void Init() { - if (_pem is not null) - throw new InvalidOperationException($"Pem can only be initilized once. Remove one of the Pem or Pem file initilizations. Issuer: {Issuer} and Audience: {Audience}"); + if(_pem is null) + { + if (File.Exists(PemPath)) + _pem = File.ReadAllText(PemPath); + else + throw new FileNotFoundException($"Pem is not assigned. Furthermore Pem file is not found in {PemPath}. Issuer is {Issuer} and audience {Audience}."); + } } } } \ No newline at end of file From 201da81aa502bc106cbac203cdb9b42ac5232de7 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Fri, 6 Dec 2024 17:17:53 +0100 Subject: [PATCH 49/61] =?UTF-8?q?refactor(RSACryptographer):=20anstatt=20P?= =?UTF-8?q?emPath.init=20zu=20verwenden,=20wurden=20getrennte=20Verzeichni?= =?UTF-8?q?s-=20und=20Dateinameneigenschaften=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Cryptographer/RSACryptographer.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs index 06e53be..82833b9 100644 --- a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs +++ b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs @@ -8,11 +8,13 @@ namespace DigitalData.Core.Security.Cryptographer { private string? _pem; - private string? _pemPath; - public virtual string Pem { get => _pem; init => _pem = value; } - public string? PemPath { get => _pemPath; init => _pemPath = value; } + public string? PemPath => FileName is null ? null : Path.Combine(Directory, FileName); + + public string Directory { get; init; } = string.Empty; + + public string? FileName { get; init; } public RSAEncryptionPadding Padding { get; init; } = RSAEncryptionPadding.OaepSHA256; From f79d2e2352728e708c935b0e87f6162dda2bf5b3 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Fri, 6 Dec 2024 17:22:42 +0100 Subject: [PATCH 50/61] refactor(IRSACryptographer): IJsonOnDeserialized-Implementierung entfernt --- .../Security/IRSACryptographer.cs | 2 +- .../Cryptographer/RSACryptographer.cs | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs b/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs index 4472344..8c1f9ef 100644 --- a/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs +++ b/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs @@ -3,7 +3,7 @@ using System.Text.Json.Serialization; namespace DigitalData.Core.Abstractions.Security { - public interface IRSACryptographer : IJsonOnDeserialized + public interface IRSACryptographer { public string Pem { get; init; } diff --git a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs index 82833b9..fc9e2ff 100644 --- a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs +++ b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs @@ -4,7 +4,7 @@ using System.Text.Json.Serialization; namespace DigitalData.Core.Security.Cryptographer { - public class RSACryptographer : IRSACryptographer, IJsonOnDeserialized + public class RSACryptographer : IRSACryptographer { private string? _pem; @@ -25,12 +25,7 @@ namespace DigitalData.Core.Security.Cryptographer public string Audience { get; init; } = string.Empty; internal RSACryptographer() { } - - public void OnDeserialized() - { - Init(); - } - + // TODO: make file read asynchronous, consider multiple routing public virtual void Init() { From 3f61b5064ccd5a58ddd8a7de208a0b5b9d844543 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Fri, 6 Dec 2024 17:27:03 +0100 Subject: [PATCH 51/61] refactor(RSACryptographer): Verzeichnis- und Dateinamen-Intter in Setter umwandeln --- DigitalData.Core.Security/Cryptographer/RSACryptographer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs index fc9e2ff..40ed9bc 100644 --- a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs +++ b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs @@ -12,9 +12,9 @@ namespace DigitalData.Core.Security.Cryptographer public string? PemPath => FileName is null ? null : Path.Combine(Directory, FileName); - public string Directory { get; init; } = string.Empty; + public string Directory { get; set; } = string.Empty; - public string? FileName { get; init; } + public string? FileName { get; set; } public RSAEncryptionPadding Padding { get; init; } = RSAEncryptionPadding.OaepSHA256; From 0c6c84852d0ad0d436a5ed72222175c0ebb3e844 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Sat, 7 Dec 2024 00:57:10 +0100 Subject: [PATCH 52/61] =?UTF-8?q?refactor:=20Validierung=20f=C3=BCr=20Pem-?= =?UTF-8?q?Eigenschaft=20hinzugef=C3=BCgt,=20um=20Ausnahme=20bei=20Nicht-I?= =?UTF-8?q?nitialisierung=20auszul=C3=B6sen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Die Pem-Eigenschaft wurde aktualisiert, um eine Validierung hinzuzufügen, die eine InvalidOperationException auslöst, falls sie vor der Initialisierung aufgerufen wird. - Nicht verwendeten Import System.Text.Json.Serialization entfernt. - Fehlermeldungen wurden erweitert, um Issuer und Audience für eine bessere Debugging-Kontextbereitschaft einzuschließen. --- .../Security/IRSACryptographer.cs | 3 --- .../Cryptographer/RSACryptographer.cs | 8 +++++-- .../Cryptographer/RSADecryptor.cs | 24 +++++++------------ .../Cryptographer/RSAEncryptor.cs | 18 ++++++-------- 4 files changed, 22 insertions(+), 31 deletions(-) diff --git a/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs b/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs index 8c1f9ef..9bbeb98 100644 --- a/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs +++ b/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs @@ -1,5 +1,4 @@ using System.Security.Cryptography; -using System.Text.Json.Serialization; namespace DigitalData.Core.Abstractions.Security { @@ -12,7 +11,5 @@ namespace DigitalData.Core.Abstractions.Security public string Issuer { get; init; } public string Audience { get; init; } - - public void Init(); } } \ No newline at end of file diff --git a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs index 40ed9bc..b7b15c7 100644 --- a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs +++ b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs @@ -1,6 +1,5 @@ using DigitalData.Core.Abstractions.Security; using System.Security.Cryptography; -using System.Text.Json.Serialization; namespace DigitalData.Core.Security.Cryptographer { @@ -8,7 +7,12 @@ namespace DigitalData.Core.Security.Cryptographer { private string? _pem; - public virtual string Pem { get => _pem; init => _pem = value; } + public string Pem + { + get => _pem + ?? throw new InvalidOperationException($"Pem is not initialized. Please ensure that the PEM is set or properly loaded from the file. Issuer: {Issuer}, Audience: {Audience}."); + init => _pem = value; + } public string? PemPath => FileName is null ? null : Path.Combine(Directory, FileName); diff --git a/DigitalData.Core.Security/Cryptographer/RSADecryptor.cs b/DigitalData.Core.Security/Cryptographer/RSADecryptor.cs index b1bf7b1..c9a541e 100644 --- a/DigitalData.Core.Security/Cryptographer/RSADecryptor.cs +++ b/DigitalData.Core.Security/Cryptographer/RSADecryptor.cs @@ -27,10 +27,6 @@ namespace DigitalData.Core.Security.Cryptographer public IRSAEncryptor Encryptor => _lazyEncryptor.Value; - private readonly Lazy lazyRSA; - - protected override RSA RSA => lazyRSA.Value; - public RSADecryptor() { _lazyEncryptor = new(() => new RSAEncryptor() @@ -38,21 +34,19 @@ namespace DigitalData.Core.Security.Cryptographer Pem = RSA.ExportRSAPublicKeyPem(), Padding = Padding }); - - lazyRSA = new(() => - { - var rsa = RSA.Create(); - if (_password is null) - RSA.ImportFromPem(Pem); - else - RSA.ImportFromEncryptedPem(Pem, _password.AsSpan()); - - return rsa; - }); } public byte[] Decrypt(byte[] data) => RSA.Decrypt(data, Padding); public string Decrypt(string data) => RSA.Decrypt(data.Base64ToByte(), Padding).BytesToString(); + + public override void Init() + { + base.Init(); + if (_password is null) + RSA.ImportFromPem(Pem); + else + RSA.ImportFromEncryptedPem(Pem, _password.AsSpan()); + } } } \ No newline at end of file diff --git a/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs b/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs index 055a6bc..f25f64e 100644 --- a/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs +++ b/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs @@ -4,21 +4,17 @@ using DigitalData.Core.Security.Extensions; namespace DigitalData.Core.Security.Cryptographer { public class RSAEncryptor : RSACryptographer, IRSAEncryptor, IRSACryptographer - { - public override string Pem - { - get => base.Pem; - init - { - RSA.ImportFromPem(base.Pem); - base.Pem = value; - } - } - + { public byte[] Encrypt(byte[] data) => RSA.Encrypt(data, Padding); public string Encrypt(string data) => RSA.Encrypt(data.Base64ToByte(), Padding).BytesToString(); public bool Verify(string data, string signature) => Encrypt(data) == signature; + + public override void Init() + { + base.Init(); + RSA.ImportFromPem(base.Pem); + } } } \ No newline at end of file From dbfee49dee48f4be28cf690f089004c61f5e4ec7 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Sat, 7 Dec 2024 01:14:13 +0100 Subject: [PATCH 53/61] =?UTF-8?q?refactor(RSADecryptor):=20RSADecryptor,?= =?UTF-8?q?=20Version=20und=20Passwort=20entfernen=20und=20hinzuf=C3=BCgen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Security/IRSADecryptor.cs | 6 +---- .../Cryptographer/RSADecryptor.cs | 23 ++++--------------- 2 files changed, 5 insertions(+), 24 deletions(-) diff --git a/DigitalData.Core.Abstractions/Security/IRSADecryptor.cs b/DigitalData.Core.Abstractions/Security/IRSADecryptor.cs index 376684e..4aa3ad9 100644 --- a/DigitalData.Core.Abstractions/Security/IRSADecryptor.cs +++ b/DigitalData.Core.Abstractions/Security/IRSADecryptor.cs @@ -2,11 +2,7 @@ { public interface IRSADecryptor : IRSACryptographer { - (string Value, Version Version)? VersionedPassword { init; } - - Version? PasswordVersion { get; } - - bool HasEncryptedPem { get; } + public bool Encrypt { get; init; } IRSAEncryptor Encryptor { get; } diff --git a/DigitalData.Core.Security/Cryptographer/RSADecryptor.cs b/DigitalData.Core.Security/Cryptographer/RSADecryptor.cs index c9a541e..eb4cbec 100644 --- a/DigitalData.Core.Security/Cryptographer/RSADecryptor.cs +++ b/DigitalData.Core.Security/Cryptographer/RSADecryptor.cs @@ -6,22 +6,7 @@ namespace DigitalData.Core.Security.Cryptographer { public class RSADecryptor : RSACryptographer, IRSADecryptor, IRSACryptographer { - public (string Value, Version Version)? VersionedPassword - { - init - { - _password = value?.Value; - PasswordVersion = value?.Version; - } - } - - private string? _password; - - public Version? PasswordVersion { get; private init; } = null; - - public bool HasEncryptedPem => _password is not null; - - public bool IsEncrypted => _password is not null; + public bool Encrypt { get; init; } private readonly Lazy _lazyEncryptor; @@ -43,10 +28,10 @@ namespace DigitalData.Core.Security.Cryptographer public override void Init() { base.Init(); - if (_password is null) - RSA.ImportFromPem(Pem); + if (Encrypt) + RSA.ImportFromEncryptedPem(Pem, Secrets.PBE_PASSWORD.AsSpan()); else - RSA.ImportFromEncryptedPem(Pem, _password.AsSpan()); + RSA.ImportFromPem(Pem); } } } \ No newline at end of file From 5c09d7775be84fd95e14c6943d9f6a30f719e9a1 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Sat, 7 Dec 2024 01:25:35 +0100 Subject: [PATCH 54/61] =?UTF-8?q?feat(RSACryptographer):=20Virtuelle=20Fil?= =?UTF-8?q?eNotFoundEvent-Methode=20f=C3=BCr=20nicht=20gefundene=20Pem-Dat?= =?UTF-8?q?ei=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Cryptographer/RSACryptographer.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs index b7b15c7..163d4bf 100644 --- a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs +++ b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs @@ -30,15 +30,20 @@ namespace DigitalData.Core.Security.Cryptographer internal RSACryptographer() { } + public virtual void FileNotFoundEvent() => throw new FileNotFoundException( + $"Pem is not initialized and pem file is not found in {PemPath}. Issuer is {Issuer} and audience {Audience}."); + // TODO: make file read asynchronous, consider multiple routing public virtual void Init() { if(_pem is null) { + if(PemPath is null) + throw new InvalidOperationException($"Pem is not initialized and pem file is null. Issuer is {Issuer} and audience {Audience}."); if (File.Exists(PemPath)) _pem = File.ReadAllText(PemPath); else - throw new FileNotFoundException($"Pem is not assigned. Furthermore Pem file is not found in {PemPath}. Issuer is {Issuer} and audience {Audience}."); + FileNotFoundEvent(); } } } From 50e25817275254443d5fcd4f6ec9a4fb0913699b Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Sat, 7 Dec 2024 01:33:56 +0100 Subject: [PATCH 55/61] =?UTF-8?q?feat(RSACryptographer):=20Virtuelle=20Una?= =?UTF-8?q?bleToInitPemEvent-Methode=20f=C3=BCr=20den=20Fall=20hinzugef?= =?UTF-8?q?=C3=BCgt,=20dass=20sowohl=20pem=20als=20auch=20pem-Pfad=20null?= =?UTF-8?q?=20sein=20k=C3=B6nnen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DigitalData.Core.Security/Cryptographer/RSACryptographer.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs index 163d4bf..f6d3152 100644 --- a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs +++ b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs @@ -30,6 +30,9 @@ namespace DigitalData.Core.Security.Cryptographer internal RSACryptographer() { } + public virtual void UnableToInitPemEvent() => throw new InvalidOperationException( + $"Pem is not initialized and pem file is null. Issuer is {Issuer} and audience {Audience}."); + public virtual void FileNotFoundEvent() => throw new FileNotFoundException( $"Pem is not initialized and pem file is not found in {PemPath}. Issuer is {Issuer} and audience {Audience}."); @@ -39,7 +42,7 @@ namespace DigitalData.Core.Security.Cryptographer if(_pem is null) { if(PemPath is null) - throw new InvalidOperationException($"Pem is not initialized and pem file is null. Issuer is {Issuer} and audience {Audience}."); + UnableToInitPemEvent(); if (File.Exists(PemPath)) _pem = File.ReadAllText(PemPath); else From 38bd23d012b055fe2ac57a393afc7a4d3745cf62 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Sat, 7 Dec 2024 02:01:06 +0100 Subject: [PATCH 56/61] refactor(RSAFactory): Entfernen der Methode ReadRSADecryptorAsync. --- .../Security/IRSAFactory.cs | 2 -- .../Config/AsymCryptParams.cs | 1 + .../Config/RSAFactoryParams.cs | 2 +- .../Cryptographer/RSAFactory.cs | 21 ------------------- 4 files changed, 2 insertions(+), 24 deletions(-) diff --git a/DigitalData.Core.Abstractions/Security/IRSAFactory.cs b/DigitalData.Core.Abstractions/Security/IRSAFactory.cs index 0dfea9d..7ff812e 100644 --- a/DigitalData.Core.Abstractions/Security/IRSAFactory.cs +++ b/DigitalData.Core.Abstractions/Security/IRSAFactory.cs @@ -12,7 +12,5 @@ namespace DigitalData.Core.Abstractions.Security PbeEncryptionAlgorithm? pbeEncryptionAlgorithm = null, HashAlgorithmName? hashAlgorithmName = null, int? iterationCount = null); - - Task ReadRSADecryptorAsync(string path, Version? version = null, CancellationToken cancellationToken = default); } } \ No newline at end of file diff --git a/DigitalData.Core.Security/Config/AsymCryptParams.cs b/DigitalData.Core.Security/Config/AsymCryptParams.cs index 0e167a8..edaa53b 100644 --- a/DigitalData.Core.Security/Config/AsymCryptParams.cs +++ b/DigitalData.Core.Security/Config/AsymCryptParams.cs @@ -1,4 +1,5 @@ using DigitalData.Core.Abstractions.Security; +using System.Text.Json.Serialization; namespace DigitalData.Core.Security.Config { diff --git a/DigitalData.Core.Security/Config/RSAFactoryParams.cs b/DigitalData.Core.Security/Config/RSAFactoryParams.cs index 7b1bd54..5ab57f2 100644 --- a/DigitalData.Core.Security/Config/RSAFactoryParams.cs +++ b/DigitalData.Core.Security/Config/RSAFactoryParams.cs @@ -22,6 +22,6 @@ namespace DigitalData.Core.Security.Config [JsonIgnore] public PbeParameters PbeParameters => _pbeParameters!; - public void OnDeserialized() => _pbeParameters = new PbeParameters(PbeEncryptionAlgorithm, PbeHashAlgorithmName, PbeIterationCount); + public virtual void OnDeserialized() => _pbeParameters = new PbeParameters(PbeEncryptionAlgorithm, PbeHashAlgorithmName, PbeIterationCount); } } \ No newline at end of file diff --git a/DigitalData.Core.Security/Cryptographer/RSAFactory.cs b/DigitalData.Core.Security/Cryptographer/RSAFactory.cs index ebdc603..ee4cca9 100644 --- a/DigitalData.Core.Security/Cryptographer/RSAFactory.cs +++ b/DigitalData.Core.Security/Cryptographer/RSAFactory.cs @@ -40,26 +40,5 @@ namespace DigitalData.Core.Security.Cryptographer return new string(pemChars); } - - public async Task ReadRSADecryptorAsync(string path, Version? version = null, CancellationToken cancellationToken = default) - { - var pem = await File.ReadAllTextAsync(path, cancellationToken); - - (string Value, Version Version)? versionedPassword = null; - - if (version is not null) - { - if (version != Secrets.Version) - throw new InvalidOperationException($"The provided version {version} does not match the expected version {Secrets.Version}."); - - versionedPassword = (Secrets.PBE_PASSWORD, Secrets.Version); - } - - return new RSADecryptor() - { - Pem = pem, - VersionedPassword = versionedPassword - }; - } } } \ No newline at end of file From fa5d0f1b26473de1de0ff5821a53dac53a0f36d7 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Sat, 7 Dec 2024 02:09:32 +0100 Subject: [PATCH 57/61] =?UTF-8?q?refactor(IRSACryptographer):=20Init-Metho?= =?UTF-8?q?de,=20Verzeichnis-=20und=20Dateinamen-Getter-Setter=20hinzugef?= =?UTF-8?q?=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Security/IRSACryptographer.cs | 6 ++++++ .../Config/AsymCryptParams.cs | 14 ++++++++++++++ .../Cryptographer/RSACryptographer.cs | 4 ++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs b/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs index 9bbeb98..f2d29bd 100644 --- a/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs +++ b/DigitalData.Core.Abstractions/Security/IRSACryptographer.cs @@ -8,8 +8,14 @@ namespace DigitalData.Core.Abstractions.Security public RSAEncryptionPadding Padding { get; init; } + public string? Directory { get; set; } + + public string? FileName { get; set; } + public string Issuer { get; init; } public string Audience { get; init; } + + public void Init(); } } \ No newline at end of file diff --git a/DigitalData.Core.Security/Config/AsymCryptParams.cs b/DigitalData.Core.Security/Config/AsymCryptParams.cs index edaa53b..30a84e9 100644 --- a/DigitalData.Core.Security/Config/AsymCryptParams.cs +++ b/DigitalData.Core.Security/Config/AsymCryptParams.cs @@ -8,5 +8,19 @@ namespace DigitalData.Core.Security.Config public IEnumerable Decryptors { get; init; } = new List(); public IEnumerable Encryptors { get; init; } = new List(); + + public override void OnDeserialized() + { + base.OnDeserialized(); + + foreach (var decryptor in Decryptors) + { + // set default path + if(decryptor.Pem is null && decryptor.FileName is null) + dec + + decryptor.Init(); + } + } } } \ No newline at end of file diff --git a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs index f6d3152..b86a42e 100644 --- a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs +++ b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs @@ -14,9 +14,9 @@ namespace DigitalData.Core.Security.Cryptographer init => _pem = value; } - public string? PemPath => FileName is null ? null : Path.Combine(Directory, FileName); + public string? PemPath => FileName is null ? null : Path.Combine(Directory ?? string.Empty, FileName); - public string Directory { get; set; } = string.Empty; + public string? Directory { get; set; } public string? FileName { get; set; } From 08ffe821ff37edca2822f8e9af0cfee26adcf9f2 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Sat, 7 Dec 2024 03:06:57 +0100 Subject: [PATCH 58/61] =?UTF-8?q?fix:=20Nullpr=C3=BCfungen=20und=20Initial?= =?UTF-8?q?isierung=20nach=20der=20Deserialisierung=20hinzuf=C3=BCgen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Nullprüfungen in `OnDeserialized` implementiert, um `Directory` und `FileName` für Decryptoren festzulegen. - `FileName` mit `FileNameFormat` dynamisch erstellt. - `TypeTagOf` verfeinert, um den richtigen Tag zu bestimmen, und Fehlerbehandlung für nicht unterstützte Kryptografietypen hinzugefügt. --- .../Config/AsymCryptParams.cs | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/DigitalData.Core.Security/Config/AsymCryptParams.cs b/DigitalData.Core.Security/Config/AsymCryptParams.cs index 30a84e9..52e3a61 100644 --- a/DigitalData.Core.Security/Config/AsymCryptParams.cs +++ b/DigitalData.Core.Security/Config/AsymCryptParams.cs @@ -1,13 +1,36 @@ using DigitalData.Core.Abstractions.Security; -using System.Text.Json.Serialization; namespace DigitalData.Core.Security.Config { public class AsymCryptParams : RSAFactoryParams { + public string Directory { get; init; } = string.Empty; + + /// + /// 0: Issuer - 1: Audience - 2: Type tag - 3: Version + /// + public string FileNameFormat { get; init; } = "{0}_-_{1}_-_{2}_-_{3}.pem"; + + public string EncryptorTag { get; init; } = "public"; + + public string DecryptorTag { get; init; } = "private"; + + public string EncryptedDecryptorTag { get; init; } = "enc-private"; + public IEnumerable Decryptors { get; init; } = new List(); public IEnumerable Encryptors { get; init; } = new List(); + + private string TypeTagOf(IRSACryptographer crypt) + { + if (crypt is IRSAEncryptor) + return EncryptorTag; + else if (crypt is IRSADecryptor decryptor) + return decryptor.Encrypt ? EncryptedDecryptorTag : DecryptorTag; + else + throw new InvalidOperationException( + "Unknown cryptographer type. The crypt parameter must be either IRSAEncryptor or IRSADecryptor."); + } public override void OnDeserialized() { @@ -16,8 +39,16 @@ namespace DigitalData.Core.Security.Config foreach (var decryptor in Decryptors) { // set default path - if(decryptor.Pem is null && decryptor.FileName is null) - dec + if (decryptor.Pem is null) + { + decryptor.Directory ??= Directory; + decryptor.FileName ??= string.Format( + FileNameFormat, + decryptor.Issuer, + decryptor.Audience, + TypeTagOf(decryptor), + Secrets.Version); + } decryptor.Init(); } From 0bfec426d4cf7c4fb925fdda256ddd3bfbc4bb73 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Sat, 7 Dec 2024 03:10:29 +0100 Subject: [PATCH 59/61] refactor: Mergen von Encryptors und Decryptors in eine einzelne Sammlung MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Kombiniert `Encryptors` und `Decryptors` in `cryptographers` für eine vereinfachte Initialisierung in `OnDeserialized`. --- .../Config/AsymCryptParams.cs | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/DigitalData.Core.Security/Config/AsymCryptParams.cs b/DigitalData.Core.Security/Config/AsymCryptParams.cs index 52e3a61..5bbc93f 100644 --- a/DigitalData.Core.Security/Config/AsymCryptParams.cs +++ b/DigitalData.Core.Security/Config/AsymCryptParams.cs @@ -36,21 +36,23 @@ namespace DigitalData.Core.Security.Config { base.OnDeserialized(); - foreach (var decryptor in Decryptors) + var cryptographers = Encryptors.Cast().Concat(Decryptors.Cast()); + + foreach (var crypt in cryptographers) { // set default path - if (decryptor.Pem is null) + if (crypt.Pem is null) { - decryptor.Directory ??= Directory; - decryptor.FileName ??= string.Format( + crypt.Directory ??= Directory; + crypt.FileName ??= string.Format( FileNameFormat, - decryptor.Issuer, - decryptor.Audience, - TypeTagOf(decryptor), + crypt.Issuer, + crypt.Audience, + TypeTagOf(crypt), Secrets.Version); - } + } - decryptor.Init(); + crypt.Init(); } } } From 4e0e9073130b5aa94ff5c8d4f77701ae956d38db Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Sat, 7 Dec 2024 03:24:29 +0100 Subject: [PATCH 60/61] feat(RSAEncryptor): FileNotFoundEvent-Methode aktualisiert, um Datei zu erstellen, wenn nicht gefunden --- .../Cryptographer/RSACryptographer.cs | 2 +- .../Cryptographer/RSAEncryptor.cs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs index b86a42e..a38fd1e 100644 --- a/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs +++ b/DigitalData.Core.Security/Cryptographer/RSACryptographer.cs @@ -5,7 +5,7 @@ namespace DigitalData.Core.Security.Cryptographer { public class RSACryptographer : IRSACryptographer { - private string? _pem; + protected string? _pem; public string Pem { diff --git a/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs b/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs index f25f64e..be21823 100644 --- a/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs +++ b/DigitalData.Core.Security/Cryptographer/RSAEncryptor.cs @@ -1,4 +1,5 @@ using DigitalData.Core.Abstractions.Security; +using DigitalData.Core.Security.Config; using DigitalData.Core.Security.Extensions; namespace DigitalData.Core.Security.Cryptographer @@ -16,5 +17,21 @@ namespace DigitalData.Core.Security.Cryptographer base.Init(); RSA.ImportFromPem(base.Pem); } + + public override void FileNotFoundEvent() + { + var new_decryptor = new RSADecryptor() + { + Pem = RSAFactory.Static.CreateRSAPrivateKeyPem() + }; + + _pem = new_decryptor.Encryptor.Pem; + + if (PemPath is not null) + Task.Run(async () => + { + await File.WriteAllTextAsync(_pem, PemPath); + }); + } } } \ No newline at end of file From 988d1e2b16464c799445ba3104ab77f1efb82d3c Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Sat, 7 Dec 2024 03:26:00 +0100 Subject: [PATCH 61/61] feat(RSADecryptor): FileNotFoundEvent-Methode aktualisiert, um Datei zu erstellen, wenn nicht gefunden --- .../Cryptographer/RSADecryptor.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/DigitalData.Core.Security/Cryptographer/RSADecryptor.cs b/DigitalData.Core.Security/Cryptographer/RSADecryptor.cs index eb4cbec..f99ac5d 100644 --- a/DigitalData.Core.Security/Cryptographer/RSADecryptor.cs +++ b/DigitalData.Core.Security/Cryptographer/RSADecryptor.cs @@ -1,4 +1,5 @@ using DigitalData.Core.Abstractions.Security; +using DigitalData.Core.Security.Config; using DigitalData.Core.Security.Extensions; using System.Security.Cryptography; @@ -33,5 +34,22 @@ namespace DigitalData.Core.Security.Cryptographer else RSA.ImportFromPem(Pem); } + + public override void FileNotFoundEvent() + { + var new_decryptor = new RSADecryptor() + { + Pem = RSAFactory.Static.CreateRSAPrivateKeyPem(), + Encrypt = Encrypt + }; + + _pem = new_decryptor.Pem; + + if (PemPath is not null) + Task.Run(async () => + { + await File.WriteAllTextAsync(_pem, PemPath); + }); + } } } \ No newline at end of file