diff --git a/DigitalData.Core.Abstractions/Security/IAsymmetricDecryptor.cs b/DigitalData.Core.Abstractions/Security/IAsymmetricDecryptor.cs index 136f173..66a45a4 100644 --- a/DigitalData.Core.Abstractions/Security/IAsymmetricDecryptor.cs +++ b/DigitalData.Core.Abstractions/Security/IAsymmetricDecryptor.cs @@ -3,5 +3,7 @@ public interface IAsymmetricDecryptor : IAsymmetricPrivateKey { byte[] Decrypt(byte[] data); + + IAsymmetricEncryptor Encryptor { get; } } } \ No newline at end of file diff --git a/DigitalData.Core.Abstractions/Security/IAsymmetricEncryptor.cs b/DigitalData.Core.Abstractions/Security/IAsymmetricEncryptor.cs new file mode 100644 index 0000000..4074982 --- /dev/null +++ b/DigitalData.Core.Abstractions/Security/IAsymmetricEncryptor.cs @@ -0,0 +1,7 @@ +namespace DigitalData.Core.Abstractions.Security +{ + public interface IAsymmetricEncryptor : IAsymmetricPublicKey + { + public byte[] Encrypt(byte[] data); + } +} \ No newline at end of file diff --git a/DigitalData.Core.Abstractions/Security/IAsymmetricKeyFactory.cs b/DigitalData.Core.Abstractions/Security/IAsymmetricKeyFactory.cs index 488543c..b52d2f5 100644 --- a/DigitalData.Core.Abstractions/Security/IAsymmetricKeyFactory.cs +++ b/DigitalData.Core.Abstractions/Security/IAsymmetricKeyFactory.cs @@ -18,6 +18,6 @@ namespace DigitalData.Core.Abstractions.Security int? keySizeInBits = null, string? password = null); - IAsymmetricPrivateKey CreatePrivateKey(string pem, string? issuer = null, string? audience = null, bool encrypt = false, RSAEncryptionPadding? padding = null); + public IAsymmetricDecryptor CreateDecryptor(string pem, string? issuer = null, string? audience = null, bool encrypt = false, RSAEncryptionPadding? padding = null); } } \ No newline at end of file diff --git a/DigitalData.Core.Abstractions/Security/IAsymmetricPublicKey.cs b/DigitalData.Core.Abstractions/Security/IAsymmetricPublicKey.cs index 96aeda3..7d6b4c8 100644 --- a/DigitalData.Core.Abstractions/Security/IAsymmetricPublicKey.cs +++ b/DigitalData.Core.Abstractions/Security/IAsymmetricPublicKey.cs @@ -2,10 +2,5 @@ { public interface IAsymmetricPublicKey : IAsymmetricKey { - public byte[] Encrypt(byte[] data); - - public string Encrypt(string data); - - public bool Verify(string data, string signature) => Encrypt(data) == signature; } } \ No newline at end of file diff --git a/DigitalData.Core.Abstractions/Security/ICryptograph.cs b/DigitalData.Core.Abstractions/Security/ICryptograph.cs index e4c663d..69dc8b6 100644 --- a/DigitalData.Core.Abstractions/Security/ICryptograph.cs +++ b/DigitalData.Core.Abstractions/Security/ICryptograph.cs @@ -6,6 +6,6 @@ IAsymmetricDecryptor VaultDecryptor { get; } - IEnumerable PublicKeys { get; } + IEnumerable Encryptors { get; } } } \ No newline at end of file diff --git a/DigitalData.Core.Abstractions/Security/SecurityExtensions.cs b/DigitalData.Core.Abstractions/Security/SecurityExtensions.cs index 7d41486..1093aa1 100644 --- a/DigitalData.Core.Abstractions/Security/SecurityExtensions.cs +++ b/DigitalData.Core.Abstractions/Security/SecurityExtensions.cs @@ -33,7 +33,13 @@ namespace DigitalData.Core.Abstractions.Security internal static string BytesToString(this byte[] bytes) => Encoding.UTF8.GetString(bytes); + internal static string ToBase64String(this byte[] bytes) => Convert.ToBase64String(bytes); + + internal static byte[] ToBytes(this string str) => System.Text.Encoding.UTF8.GetBytes(str); + public static string Decrypt(this IAsymmetricDecryptor decryptor, string data) => decryptor .Decrypt(data.Base64ToByte()).BytesToString(); + + public static string Encrypt(this IAsymmetricEncryptor encryptor, string data) => encryptor.Encrypt(data.ToBytes()).ToBase64String(); } } \ No newline at end of file diff --git a/DigitalData.Core.Security/Cryptograph.cs b/DigitalData.Core.Security/Cryptograph.cs index 13c2468..271a209 100644 --- a/DigitalData.Core.Security/Cryptograph.cs +++ b/DigitalData.Core.Security/Cryptograph.cs @@ -15,9 +15,9 @@ namespace DigitalData.Core.Security /// public IAsymmetricDecryptor VaultDecryptor { get; } - private readonly Lazy> _lazyPublicKeys; + private readonly Lazy> _lazyEncryptors; - public IEnumerable PublicKeys => _lazyPublicKeys.Value; + public IEnumerable Encryptors => _lazyEncryptors.Value; public IEnumerable TokenDescriptions { get; init; } = new List(); @@ -36,7 +36,7 @@ namespace DigitalData.Core.Security VaultDecryptor = _params.VaultDecryptor ?? Decryptors.First(); - _lazyPublicKeys = new(Decryptors.Select(decryptor => decryptor.PublicKey)); + _lazyEncryptors = new(Decryptors.Select(decryptor => decryptor.Encryptor)); } } } \ No newline at end of file diff --git a/DigitalData.Core.Security/Extension.cs b/DigitalData.Core.Security/Extension.cs index b8262ba..347c622 100644 --- a/DigitalData.Core.Security/Extension.cs +++ b/DigitalData.Core.Security/Extension.cs @@ -6,10 +6,6 @@ namespace DigitalData.Core.Security { internal static class Extension { - internal static string ToBase64String(this byte[] bytes) => Convert.ToBase64String(bytes); - - internal static byte[] ToBytes(this string str) => System.Text.Encoding.UTF8.GetBytes(str); - /// /// Converts a to a formatted string based on the specified format string. ///
diff --git a/DigitalData.Core.Security/RSAKey/RSADecryptor.cs b/DigitalData.Core.Security/RSAKey/RSADecryptor.cs index 406eae4..ba35d43 100644 --- a/DigitalData.Core.Security/RSAKey/RSADecryptor.cs +++ b/DigitalData.Core.Security/RSAKey/RSADecryptor.cs @@ -1,9 +1,33 @@ using DigitalData.Core.Abstractions.Security; +using System.Reflection; +using System.Security.Cryptography; namespace DigitalData.Core.Security.RSAKey { public class RSADecryptor : RSAPrivateKey, IAsymmetricDecryptor { + public RSAEncryptionPadding Padding { get; init; } = RSAEncryptionPadding.OaepSHA256; + + // TODO: add as json converter to IConfigurIConfiguration.Config + public string PaddingName + { + get => Padding.ToString(); + init => Padding = typeof(RSAEncryptionPadding).GetProperty(value, BindingFlags.Public | BindingFlags.Static)?.GetValue(null) as RSAEncryptionPadding ?? throw new ArgumentException($"Padding '{value}' not found."); + } + public byte[] Decrypt(byte[] data) => RSA.Decrypt(data, Padding); + + private readonly Lazy _lazyEncryptor; + + public IAsymmetricEncryptor Encryptor => _lazyEncryptor.Value; + + public RSADecryptor() + { + _lazyEncryptor = new(() => new RSAEncryptor() + { + Content = RSA.ExportRSAPublicKeyPem(), + Padding = Padding + }); + } } } \ No newline at end of file diff --git a/DigitalData.Core.Security/RSAKey/RSAEncryptor.cs b/DigitalData.Core.Security/RSAKey/RSAEncryptor.cs new file mode 100644 index 0000000..8fb87e8 --- /dev/null +++ b/DigitalData.Core.Security/RSAKey/RSAEncryptor.cs @@ -0,0 +1,20 @@ +using DigitalData.Core.Abstractions.Security; +using System.Reflection; +using System.Security.Cryptography; + +namespace DigitalData.Core.Security.RSAKey +{ + public class RSAEncryptor : RSAPublicKey, IAsymmetricEncryptor + { + public RSAEncryptionPadding Padding { get; init; } = RSAEncryptionPadding.OaepSHA256; + + // TODO: add as json converter to IConfigurIConfiguration.Config + public string PaddingName + { + get => Padding.ToString(); + init => Padding = typeof(RSAEncryptionPadding).GetProperty(value, BindingFlags.Public | BindingFlags.Static)?.GetValue(null) as RSAEncryptionPadding ?? throw new ArgumentException($"Padding '{value}' not found."); + } + + public byte[] Encrypt(byte[] data) => RSA.Encrypt(data, Padding); + } +} \ No newline at end of file diff --git a/DigitalData.Core.Security/RSAKey/RSAFactory.cs b/DigitalData.Core.Security/RSAKey/RSAFactory.cs index db789a0..6142e31 100644 --- a/DigitalData.Core.Security/RSAKey/RSAFactory.cs +++ b/DigitalData.Core.Security/RSAKey/RSAFactory.cs @@ -56,7 +56,7 @@ namespace DigitalData.Core.Security.RSAKey return new string(pemChars); } - public IAsymmetricPrivateKey CreatePrivateKey(string pem, string? issuer = null, string? audience = null, bool encrypt = false, RSAEncryptionPadding? padding = null) => new RSAPrivateKey() + public IAsymmetricDecryptor CreateDecryptor(string pem, string? issuer = null, string? audience = null, bool encrypt = false, RSAEncryptionPadding? padding = null) => new RSADecryptor() { Content = pem, Issuer = issuer ?? string.Empty, diff --git a/DigitalData.Core.Security/RSAKey/RSAKeyBase.cs b/DigitalData.Core.Security/RSAKey/RSAKeyBase.cs index f2bb84f..d076c88 100644 --- a/DigitalData.Core.Security/RSAKey/RSAKeyBase.cs +++ b/DigitalData.Core.Security/RSAKey/RSAKeyBase.cs @@ -8,16 +8,7 @@ namespace DigitalData.Core.Security.RSAKey public class RSAKeyBase : IAsymmetricKey { public virtual string Content { get; init; } - - public RSAEncryptionPadding Padding { get; init; } = RSAEncryptionPadding.OaepSHA256; - - // TODO: add as json converter to IConfigurIConfiguration.Config - public string PaddingName - { - get => Padding.ToString(); - init => Padding = typeof(RSAEncryptionPadding).GetProperty(value, BindingFlags.Public | BindingFlags.Static)?.GetValue(null) as RSAEncryptionPadding ?? throw new ArgumentException($"Padding '{value}' not found."); - } - + protected virtual RSA RSA { get; } = RSA.Create(); public string Issuer { get; init; } = string.Empty; diff --git a/DigitalData.Core.Security/RSAKey/RSAPrivateKey.cs b/DigitalData.Core.Security/RSAKey/RSAPrivateKey.cs index 00f86ed..a0901a4 100644 --- a/DigitalData.Core.Security/RSAKey/RSAPrivateKey.cs +++ b/DigitalData.Core.Security/RSAKey/RSAPrivateKey.cs @@ -38,8 +38,7 @@ namespace DigitalData.Core.Security.RSAKey { _lazyPublicKey = new(() => new RSAPublicKey() { - Content = RSA.ExportRSAPublicKeyPem(), - Padding = Padding + Content = RSA.ExportRSAPublicKeyPem() }); _descriptorInitiator = new(() => diff --git a/DigitalData.Core.Security/RSAKey/RSAPublicKey.cs b/DigitalData.Core.Security/RSAKey/RSAPublicKey.cs index efcd335..96a7210 100644 --- a/DigitalData.Core.Security/RSAKey/RSAPublicKey.cs +++ b/DigitalData.Core.Security/RSAKey/RSAPublicKey.cs @@ -13,11 +13,5 @@ namespace DigitalData.Core.Security.RSAKey RSA.ImportFromPem(value); } } - - public byte[] Encrypt(byte[] data) => RSA.Encrypt(data, Padding); - - public string Encrypt(string data) => RSA.Encrypt(data.ToBytes(), Padding).ToBase64String(); - - public bool Verify(string data, string signature) => Encrypt(data) == signature; } } \ No newline at end of file