diff --git a/SafeCrypt.sln b/SafeCrypt.sln index cd54c71..c639949 100644 --- a/SafeCrypt.sln +++ b/SafeCrypt.sln @@ -3,9 +3,15 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.8.34322.80 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SafeCrypt", "SafeCrypt.csproj", "{204CA507-752E-43A6-A094-794E40ABAE1F}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{0B7C0C60-9850-4554-AF85-86C0378B6B16}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "safecrypt-testapp", "..\safecrypt-testapp\safecrypt-testapp.csproj", "{76D17C56-5643-4148-A504-8D6E24D24CAD}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SafeCrypt.Lib", "SafeCrypt.Lib", "{8507D130-9F07-426C-8EE6-0AC714CF72E5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SafeCrypt.App", "SafeCrypt.App", "{1D91E775-F63F-4537-B81E-B8F9A6480D6D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SafeCrypt", "src\SafeCrypt.Lib\SafeCrypt.csproj", "{AE9FAE54-9854-4F98-A60F-19125CEAA3A8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SafeCrypt.App", "src\SafeCrypt.Test\SafeCrypt.App.csproj", "{DAD7FFA3-AABC-47FF-BA79-0C9531BFBBE6}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -13,18 +19,24 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {204CA507-752E-43A6-A094-794E40ABAE1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {204CA507-752E-43A6-A094-794E40ABAE1F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {204CA507-752E-43A6-A094-794E40ABAE1F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {204CA507-752E-43A6-A094-794E40ABAE1F}.Release|Any CPU.Build.0 = Release|Any CPU - {76D17C56-5643-4148-A504-8D6E24D24CAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {76D17C56-5643-4148-A504-8D6E24D24CAD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {76D17C56-5643-4148-A504-8D6E24D24CAD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {76D17C56-5643-4148-A504-8D6E24D24CAD}.Release|Any CPU.Build.0 = Release|Any CPU + {AE9FAE54-9854-4F98-A60F-19125CEAA3A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AE9FAE54-9854-4F98-A60F-19125CEAA3A8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AE9FAE54-9854-4F98-A60F-19125CEAA3A8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AE9FAE54-9854-4F98-A60F-19125CEAA3A8}.Release|Any CPU.Build.0 = Release|Any CPU + {DAD7FFA3-AABC-47FF-BA79-0C9531BFBBE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DAD7FFA3-AABC-47FF-BA79-0C9531BFBBE6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DAD7FFA3-AABC-47FF-BA79-0C9531BFBBE6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DAD7FFA3-AABC-47FF-BA79-0C9531BFBBE6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {8507D130-9F07-426C-8EE6-0AC714CF72E5} = {0B7C0C60-9850-4554-AF85-86C0378B6B16} + {1D91E775-F63F-4537-B81E-B8F9A6480D6D} = {0B7C0C60-9850-4554-AF85-86C0378B6B16} + {AE9FAE54-9854-4F98-A60F-19125CEAA3A8} = {8507D130-9F07-426C-8EE6-0AC714CF72E5} + {DAD7FFA3-AABC-47FF-BA79-0C9531BFBBE6} = {1D91E775-F63F-4537-B81E-B8F9A6480D6D} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {639A4359-2BA4-4F71-9EBF-D6EAB68C84CB} EndGlobalSection diff --git a/src/Enums/ReturnType.cs b/src/Enums/ReturnType.cs deleted file mode 100644 index 2a7007a..0000000 --- a/src/Enums/ReturnType.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace SafeCrypt.Enums -{ - public enum ReturnType - { - Hex = 1, - Bytes - } -} diff --git a/src/Encryption/AesEncryption/BaseAesEncryption.cs b/src/SafeCrypt.Lib/Encryption/AesEncryption/BaseAesEncryption.cs similarity index 96% rename from src/Encryption/AesEncryption/BaseAesEncryption.cs rename to src/SafeCrypt.Lib/Encryption/AesEncryption/BaseAesEncryption.cs index 9a35ca9..b9febab 100644 --- a/src/Encryption/AesEncryption/BaseAesEncryption.cs +++ b/src/SafeCrypt.Lib/Encryption/AesEncryption/BaseAesEncryption.cs @@ -1,9 +1,7 @@ using SafeCrypt.Models; using System; using System.IO; -using System.Reflection; using System.Security.Cryptography; -using System.Text; namespace SafeCrypt.AesEncryption { @@ -25,7 +23,7 @@ public class BaseAesEncryption /// /// Thrown for general encryption-related exceptions. /// - internal static byte[] EncryptAES(ByteEncryptionParameters param) + internal static byte[] EncryptAES(ByteEncryptionParameters param, CipherMode mode = CipherMode.CBC) { try { @@ -35,6 +33,7 @@ internal static byte[] EncryptAES(ByteEncryptionParameters param) // Set the key and initialization vector aes.Key = param.SecretKey; aes.IV = param.IV; + aes.Mode = mode; // Create an encryptor using the key and initialization vector ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV); @@ -73,7 +72,7 @@ internal static byte[] EncryptAES(ByteEncryptionParameters param) /// /// Thrown if the input encrypted data, key, or initialization vector is null. /// - internal static byte[] DecryptAES(ByteDecryptionParameters param) + internal static byte[] DecryptAES(ByteDecryptionParameters param, CipherMode mode = CipherMode.CBC) { try { @@ -83,6 +82,7 @@ internal static byte[] DecryptAES(ByteDecryptionParameters param) // Set the key and initialization vector aes.Key = param.SecretKey; aes.IV = param.IV; + aes.Mode= mode; // Create a decryptor using the key and initialization vector ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV); @@ -106,7 +106,6 @@ internal static byte[] DecryptAES(ByteDecryptionParameters param) } catch (Exception ex) { - throw; } } diff --git a/src/Encryption/AesEncryption/Decrypting.cs b/src/SafeCrypt.Lib/Encryption/AesEncryption/Decrypting.cs similarity index 94% rename from src/Encryption/AesEncryption/Decrypting.cs rename to src/SafeCrypt.Lib/Encryption/AesEncryption/Decrypting.cs index 4fe642b..eda6bbb 100644 --- a/src/Encryption/AesEncryption/Decrypting.cs +++ b/src/SafeCrypt.Lib/Encryption/AesEncryption/Decrypting.cs @@ -2,12 +2,13 @@ using SafeCrypt.Helpers; using SafeCrypt.Models; using System; +using System.Security.Cryptography; namespace SafeCrypt.AESDecryption { public class AesDecryption : BaseAesEncryption { - public DecryptionData DeEncryptFromHexString(DecryptionParameters param) + public DecryptionData DeEncryptFromHexString(DecryptionParameters param, CipherMode mode = CipherMode.CBC) { var responseData = new DecryptionData(); @@ -43,7 +44,7 @@ public DecryptionData DeEncryptFromHexString(DecryptionParameters param) Data = param.DataToDecrypt.HexadecimalStringToByteArray() }; - var response = DecryptAES(byteEncryptionParameters); + var response = DecryptAES(byteEncryptionParameters, mode); return new DecryptionData { @@ -53,7 +54,7 @@ public DecryptionData DeEncryptFromHexString(DecryptionParameters param) }; } - public DecryptionData DecryptFromBase64String(DecryptionParameters param) + public DecryptionData DecryptFromBase64String(DecryptionParameters param, CipherMode mode = CipherMode.CBC) { var responseData = new DecryptionData(); @@ -81,7 +82,7 @@ public DecryptionData DecryptFromBase64String(DecryptionParameters param) Data = Convert.FromBase64String(param.DataToDecrypt) }; - var response = DecryptAES(byteDecryptionParameters); + var response = DecryptAES(byteDecryptionParameters, mode); return new DecryptionData { diff --git a/src/Encryption/AesEncryption/Encrypting.cs b/src/SafeCrypt.Lib/Encryption/AesEncryption/Encrypting.cs similarity index 89% rename from src/Encryption/AesEncryption/Encrypting.cs rename to src/SafeCrypt.Lib/Encryption/AesEncryption/Encrypting.cs index 3f94479..10900ad 100644 --- a/src/Encryption/AesEncryption/Encrypting.cs +++ b/src/SafeCrypt.Lib/Encryption/AesEncryption/Encrypting.cs @@ -1,4 +1,5 @@ using System; +using System.Security.Cryptography; using SafeCrypt.AesEncryption; using SafeCrypt.Helpers; using SafeCrypt.Models; @@ -21,24 +22,17 @@ public class AesEncryption : BaseAesEncryption /// The secret key used for encryption. /// The initialization vector used for encryption. /// The encrypted data as a byte array. - public EncryptionData EncryptToHexString(EncryptionParameters param) + public EncryptionData EncryptToHexString(EncryptionParameters param, CipherMode mode = CipherMode.CBC) { var responseData = new EncryptionData(); - Validators.ValidateNotNull(param); + var parameterValidation = ValidateEncryptionParameters(param); - // validate is base64 - if (!Validators.IsBase64String(param.SecretKey)) + if (parameterValidation.HasError) { - AddError(responseData, $"SecretKey: {param.SecretKey} is not a base64 string"); - return responseData; + return parameterValidation; } - if (!Validators.IsBase64String(param.IV)) - { - AddError(responseData, $"IV: {param.IV} is not a base64 string"); - return responseData; - } // Convert input string to bytes byte[] dataBytes = param.IV.ConvertKeysToBytes(); @@ -57,7 +51,7 @@ public EncryptionData EncryptToHexString(EncryptionParameters param) Data = param.DataToEncrypt.ConvertToHexString().HexadecimalStringToByteArray() }; - var response = EncryptAES(byteEncryptionParameters); + var response = EncryptAES(byteEncryptionParameters, mode); return new EncryptionData { @@ -66,8 +60,7 @@ public EncryptionData EncryptToHexString(EncryptionParameters param) SecretKey = param.SecretKey }; } - - + /// /// Encrypts the provided string data using the Advanced Encryption Standard (AES) algorithm. /// @@ -90,7 +83,7 @@ public EncryptionData EncryptToHexString(EncryptionParameters param) /// /// Thrown if the base64secretKey is not a valid Base64-encoded string. /// - public EncryptionData EncryptToBase64String(string dataToBeEncrypted, string base64secretKey) + public EncryptionData EncryptToBase64String(string dataToBeEncrypted, string base64secretKey, CipherMode mode = CipherMode.CBC) { // validate is base64 if (!Validators.IsBase64String(base64secretKey)) @@ -110,7 +103,7 @@ public EncryptionData EncryptToBase64String(string dataToBeEncrypted, string bas Data = dataToBeEncrypted.ConvertToHexString().HexadecimalStringToByteArray() }; - var response = EncryptAES(byteEncryptionParameters); + var response = EncryptAES(byteEncryptionParameters, mode); return new EncryptionData { @@ -120,6 +113,26 @@ public EncryptionData EncryptToBase64String(string dataToBeEncrypted, string bas }; } + private EncryptionData ValidateEncryptionParameters(EncryptionParameters param) + { + var responseData = new EncryptionData(); + + Validators.ValidateNotNull(param); + + // validate is base64 + if (!Validators.IsBase64String(param.SecretKey)) + { + AddError(responseData, $"SecretKey: {param.SecretKey} is not a base64 string"); + } + + if (!Validators.IsBase64String(param.IV)) + { + AddError(responseData, $"IV: {param.IV} is not a base64 string"); + } + + return responseData; + } + private void NullChecks(string data, string secretKey) { if (data == null || data.Length <= 0) diff --git a/src/Encryption/AesEncryption/Models/ByteEncryptionParameters.cs b/src/SafeCrypt.Lib/Encryption/AesEncryption/Models/ByteEncryptionParameters.cs similarity index 91% rename from src/Encryption/AesEncryption/Models/ByteEncryptionParameters.cs rename to src/SafeCrypt.Lib/Encryption/AesEncryption/Models/ByteEncryptionParameters.cs index f5be539..0f05841 100644 --- a/src/Encryption/AesEncryption/Models/ByteEncryptionParameters.cs +++ b/src/SafeCrypt.Lib/Encryption/AesEncryption/Models/ByteEncryptionParameters.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Text; +using System.ComponentModel.DataAnnotations; namespace SafeCrypt.Models { diff --git a/src/Encryption/AesEncryption/Models/Decrypt/DecryptionData.cs b/src/SafeCrypt.Lib/Encryption/AesEncryption/Models/Decrypt/DecryptionData.cs similarity index 90% rename from src/Encryption/AesEncryption/Models/Decrypt/DecryptionData.cs rename to src/SafeCrypt.Lib/Encryption/AesEncryption/Models/Decrypt/DecryptionData.cs index 55f62d4..2f318cb 100644 --- a/src/Encryption/AesEncryption/Models/Decrypt/DecryptionData.cs +++ b/src/SafeCrypt.Lib/Encryption/AesEncryption/Models/Decrypt/DecryptionData.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Collections.Generic; namespace SafeCrypt.Models { diff --git a/src/Encryption/AesEncryption/Models/Decrypt/DecryptionParameters.cs b/src/SafeCrypt.Lib/Encryption/AesEncryption/Models/Decrypt/DecryptionParameters.cs similarity index 100% rename from src/Encryption/AesEncryption/Models/Decrypt/DecryptionParameters.cs rename to src/SafeCrypt.Lib/Encryption/AesEncryption/Models/Decrypt/DecryptionParameters.cs diff --git a/src/Encryption/AesEncryption/Models/Encrypt/EncryptionData.cs b/src/SafeCrypt.Lib/Encryption/AesEncryption/Models/Encrypt/EncryptionData.cs similarity index 91% rename from src/Encryption/AesEncryption/Models/Encrypt/EncryptionData.cs rename to src/SafeCrypt.Lib/Encryption/AesEncryption/Models/Encrypt/EncryptionData.cs index dcc6f13..8af7b78 100644 --- a/src/Encryption/AesEncryption/Models/Encrypt/EncryptionData.cs +++ b/src/SafeCrypt.Lib/Encryption/AesEncryption/Models/Encrypt/EncryptionData.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Collections.Generic; namespace SafeCrypt.Models { @@ -25,6 +23,7 @@ public class EncryptionData public string SecretKey { get; set; } public bool HasError { get; set; } + public List Errors { get; set; } = new List(); } } diff --git a/src/Encryption/AesEncryption/Models/Encrypt/EncryptionParameters.cs b/src/SafeCrypt.Lib/Encryption/AesEncryption/Models/Encrypt/EncryptionParameters.cs similarity index 91% rename from src/Encryption/AesEncryption/Models/Encrypt/EncryptionParameters.cs rename to src/SafeCrypt.Lib/Encryption/AesEncryption/Models/Encrypt/EncryptionParameters.cs index fd2363a..e329366 100644 --- a/src/Encryption/AesEncryption/Models/Encrypt/EncryptionParameters.cs +++ b/src/SafeCrypt.Lib/Encryption/AesEncryption/Models/Encrypt/EncryptionParameters.cs @@ -1,7 +1,5 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Text; +using System.ComponentModel.DataAnnotations; + namespace SafeCrypt.Models { diff --git a/src/SafeCrypt.Lib/Enums/ReturnType.cs b/src/SafeCrypt.Lib/Enums/ReturnType.cs new file mode 100644 index 0000000..4352d34 --- /dev/null +++ b/src/SafeCrypt.Lib/Enums/ReturnType.cs @@ -0,0 +1,8 @@ +namespace SafeCrypt.Enums +{ + public enum ReturnType + { + Hex = 1, + Bytes + } +} diff --git a/src/Helpers/Converters.cs b/src/SafeCrypt.Lib/Helpers/Converters.cs similarity index 99% rename from src/Helpers/Converters.cs rename to src/SafeCrypt.Lib/Helpers/Converters.cs index 57a6e3d..d254060 100644 --- a/src/Helpers/Converters.cs +++ b/src/SafeCrypt.Lib/Helpers/Converters.cs @@ -37,6 +37,7 @@ public static byte[] HexadecimalStringToByteArray(this string input) } return output; } + /// /// Converts a string to its hexadecimal representation. /// diff --git a/src/Helpers/KeyGenerators.cs b/src/SafeCrypt.Lib/Helpers/KeyGenerators.cs similarity index 71% rename from src/Helpers/KeyGenerators.cs rename to src/SafeCrypt.Lib/Helpers/KeyGenerators.cs index 1629806..44a2c5a 100644 --- a/src/Helpers/KeyGenerators.cs +++ b/src/SafeCrypt.Lib/Helpers/KeyGenerators.cs @@ -30,6 +30,24 @@ public static byte[] GenerateRandomIVKeyAsBytes(int length) return randomBytes; } + /// + /// Generates a random initialization vector (IV) key as a hexadecimal string. + /// + /// + /// A hexadecimal string representation of the randomly generated IV key. + /// + /// + /// This method internally uses the method + /// to obtain a random byte array and then converts it to a hexadecimal string using + /// . Any hyphens in the resulting string are removed + /// using . + /// + public static string GenerateRandomIVKeyAsString() + { + byte[] randomBytes = GenerateRandomIVKeyAsBytes(16); + return BitConverter.ToString(randomBytes).Replace("-", ""); + } + /// /// Generates a valid AES secret key with the specified key size. /// diff --git a/src/Helpers/Validators.cs b/src/SafeCrypt.Lib/Helpers/Validators.cs similarity index 91% rename from src/Helpers/Validators.cs rename to src/SafeCrypt.Lib/Helpers/Validators.cs index a677b3d..f06d02d 100644 --- a/src/Helpers/Validators.cs +++ b/src/SafeCrypt.Lib/Helpers/Validators.cs @@ -1,11 +1,9 @@ using SafeCrypt.Models; using System; -using System.Collections.Generic; -using System.Text; namespace SafeCrypt.Helpers { - public static class Validators + internal static class Validators { /// /// Validates that the specified ByteEncryptionParameters instance is not null @@ -15,7 +13,7 @@ public static class Validators /// /// Thrown if the specified parameters instance is null or if any of its required properties are null. /// - public static void ValidateNotNull(EncryptionParameters parameters) + internal static void ValidateNotNull(EncryptionParameters parameters) { if (parameters == null) { @@ -37,7 +35,7 @@ public static void ValidateNotNull(EncryptionParameters parameters) throw new ArgumentNullException(nameof(parameters.IV), "IV property cannot be null."); } } - public static void ValidateNotNull(DecryptionParameters parameters) + internal static void ValidateNotNull(DecryptionParameters parameters) { if (parameters == null) { @@ -60,7 +58,7 @@ public static void ValidateNotNull(DecryptionParameters parameters) } } - public static void ValidateNotNull(StringEncryptionParameters parameters) + internal static void ValidateNotNull(StringEncryptionParameters parameters) { if (parameters == null) { @@ -88,7 +86,7 @@ public static void ValidateNotNull(StringEncryptionParameters parameters) /// /// The string to validate. /// True if the string is a valid Base64-encoded key; otherwise, false. - public static bool IsBase64String(string keyAsString) + internal static bool IsBase64String(string keyAsString) { if (string.IsNullOrEmpty(keyAsString)) { @@ -111,7 +109,7 @@ public static bool IsBase64String(string keyAsString) /// /// The length of the data to be encrypted. /// True if the block size is valid; otherwise, false. - public static bool IsValidBlockSize(int dataLength) + internal static bool IsValidBlockSize(int dataLength) { // AES block size is 128 bits (16 bytes) return dataLength % 16 == 0; diff --git a/SafeCrypt.csproj b/src/SafeCrypt.Lib/SafeCrypt.csproj similarity index 91% rename from SafeCrypt.csproj rename to src/SafeCrypt.Lib/SafeCrypt.csproj index 0a16def..cf1749e 100644 --- a/SafeCrypt.csproj +++ b/src/SafeCrypt.Lib/SafeCrypt.csproj @@ -39,11 +39,15 @@ Thank you for using the SafeCrypt Library! - + True \ - + + True + \ + + True \ diff --git a/src/SafeCrypt.Test/Program.cs b/src/SafeCrypt.Test/Program.cs new file mode 100644 index 0000000..6df6ccb --- /dev/null +++ b/src/SafeCrypt.Test/Program.cs @@ -0,0 +1,40 @@ +// See https://aka.ms/new-console-template for more information + +using SafeCrypt.AESDecryption; +using SafeCrypt.AESEncryption; +using SafeCrypt.Models; + +var dataToEncrypt = "Data to Encrypt"; +var secret = "hghjuytsdfraestwsgtere=="; + +// Encryption process +var encryptor = new AesEncryption(); +// this method generates a random IV key for the encryption process +// the IV is returned in the response with other properties +var response = encryptor.EncryptToBase64String(dataToEncrypt, secret); + +//Console.WriteLine("............Encryption Started............"); + +//Console.WriteLine($"Encrypted data: {response.EncryptedData}"); +//Console.WriteLine($"IV key: {response.Iv}"); +//Console.WriteLine($"Secret key: {response.SecretKey}"); + + +// Decryption process +var decryptorParam = new DecryptionParameters +{ + IV = response.Iv, + SecretKey = secret, + DataToDecrypt = response.EncryptedData +}; + +var decryptor = new AesDecryption(); +var decryptionData = decryptor.DecryptFromBase64String(decryptorParam); + +Console.WriteLine("............Decryption Started............"); +Console.WriteLine($"Decrypted data: { decryptionData.DecryptedData }"); +Console.WriteLine($"IV key: {decryptionData.Iv}"); +Console.WriteLine($"Secret key: {decryptionData.SecretKey}"); + + +Console.WriteLine("Hello, World!"); diff --git a/src/SafeCrypt.Test/SafeCrypt.App.csproj b/src/SafeCrypt.Test/SafeCrypt.App.csproj new file mode 100644 index 0000000..c1c02fd --- /dev/null +++ b/src/SafeCrypt.Test/SafeCrypt.App.csproj @@ -0,0 +1,15 @@ + + + + Exe + net8.0 + safecrypt_testapp + enable + enable + + + + + + +