From eb59dfba37bc01c655e2dd3be18e69f61da2ed1f Mon Sep 17 00:00:00 2001 From: Raphael Anyanwu <53215747+selfmadecode@users.noreply.github.com> Date: Tue, 5 Mar 2024 09:41:20 +0100 Subject: [PATCH 01/20] Update README.md --- README.md | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 238a4b2..48e9659 100644 --- a/README.md +++ b/README.md @@ -5,12 +5,12 @@ A C# library for encryption and decryption. ## Overview The SafeCrypt library provides a set of methods for encrypting and decrypting data using various encryption algorithms, -including the Advanced Encryption Standard (AES) and RSA (Rivest–Shamir–Adleman). +including the Advanced Encryption Standard (AES) and RSA (Rivest–Shamir–Adleman). It is designed to be easy to use and can be integrated into C# applications that require secure data transmission or storage. ## Table of Contents - [Installation](#installation) -- [AES Encryption and Decryption usage](#usage) +- [AES Encryption and Decryption usage](#aes) - [RSA Encryption and Decryption usage](#rsa) - [Contributing](#contributing) - [License](#license) @@ -34,10 +34,9 @@ To use the SafeCrypt library in your C# project, follow these steps: Now, you can reference the SafeCrypt library in your C# project. -## Usage - -To use the AES encryption in your C# application, -instantiate the `AesEncryption` or `AesDecryption` class and call the provided methods. Here's a simple example: +## Aes +To use AES encryption in your C# application, access the static Aes class directly. +Call the provided methods; Here's a simple example: ```csharp using SafeCrypt.AES; @@ -61,7 +60,7 @@ class Program }; - var data = await Aes.DecryptFromBase64StringAsync(parameterToDecrypt) + var data = await Aes.DecryptFromBase64StringAsync(parameterToDecrypt); Console.WriteLine($"Decrypted Data: {data.DecryptedData}"); Console.WriteLine($"Initialization Vector: {data.Iv}"); @@ -97,8 +96,6 @@ class Program Console.WriteLine(response.Iv); Console.WriteLine(response.SecretKey); - - var decryptorParam = new DecryptionParameters { IV = response.Iv, @@ -106,7 +103,6 @@ class Program DataToDecrypt = response.EncryptedData }; - var decryptionData = await Aes.DecryptFromBase64StringAsync(decryptorParam); Console.WriteLine(decryptionData.DecryptedData); From c069d940c4ca49669681c0d5e624bc5d4596ec63 Mon Sep 17 00:00:00 2001 From: Raphael Anyanwu Date: Tue, 5 Mar 2024 13:22:30 +0100 Subject: [PATCH 02/20] modify the EncryptToBase64StringAsync method to allow users specify IV key --- .../Encryption/AesEncryption/Encrypting.cs | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/SafeCrypt.Lib/Encryption/AesEncryption/Encrypting.cs b/src/SafeCrypt.Lib/Encryption/AesEncryption/Encrypting.cs index 23e7991..91c9318 100644 --- a/src/SafeCrypt.Lib/Encryption/AesEncryption/Encrypting.cs +++ b/src/SafeCrypt.Lib/Encryption/AesEncryption/Encrypting.cs @@ -84,24 +84,32 @@ public static async Task EncryptToHexStringAsync(EncryptionParam /// /// Thrown if the base64secretKey is not a valid Base64-encoded string. /// - public static async Task EncryptToBase64StringAsync(string dataToBeEncrypted, string base64secretKey, CipherMode mode = CipherMode.CBC) + public static async Task EncryptToBase64StringAsync(EncryptionParameters param, CipherMode mode = CipherMode.CBC) { // validate is base64 - if (!Validators.IsBase64String(base64secretKey)) + var responseData = new EncryptionData(); + + var parameterValidation = ValidateEncryptionParameters(param); + + if (parameterValidation.HasError) { - return null; + return parameterValidation; } - NullChecks(data: dataToBeEncrypted, base64secretKey); + if (!Validators.IsBase64String(param.SecretKey)) + { + AddError(responseData, "Secret Key not base64"); + } // Generate a random 16-byte IV for AES in CBC mode - var aesIv = KeyGenerators.GenerateRandomIVKeyAsBytes(16); + byte[] aesIv = Convert.FromBase64String(param.IV); + var byteEncryptionParameters = new ByteEncryptionParameters { - SecretKey = Convert.FromBase64String(base64secretKey), + SecretKey = Convert.FromBase64String(param.SecretKey), IV = aesIv, - Data = dataToBeEncrypted.ConvertToHexString().HexadecimalStringToByteArray() + Data = param.Data.ConvertToHexString().HexadecimalStringToByteArray() }; var response = await BaseAesEncryption.EncryptAsync(byteEncryptionParameters, mode); @@ -109,8 +117,8 @@ public static async Task EncryptToBase64StringAsync(string dataT return new EncryptionData { EncryptedData = Convert.ToBase64String(response), - Iv = Convert.ToBase64String(aesIv), - SecretKey = base64secretKey + Iv = param.IV, + SecretKey = param.SecretKey }; } From 1c10ddf7fa8adf5408b0450817e47305603698cb Mon Sep 17 00:00:00 2001 From: Raphael Anyanwu Date: Tue, 5 Mar 2024 13:22:46 +0100 Subject: [PATCH 03/20] add Aes readme doc --- doc/Aes.md | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 doc/Aes.md diff --git a/doc/Aes.md b/doc/Aes.md new file mode 100644 index 0000000..bb7da1b --- /dev/null +++ b/doc/Aes.md @@ -0,0 +1,177 @@ +what is secret, what is the length +what is IV, what is the lenght, IV as base 64, IV as hex +how to generate default IV with the package + + +# SafeCrypt AES Encryption and Decryption + +## Overview + +The SafeCrypt library provides a simple and secure implementation of the Advanced Encryption Standard (AES) algorithm for +encryption and decryption in C#. +This document guides you through the basic steps to use AES encryption and decryption methods. + +## Table of Contents + +- [Usage](#usage) + - [EncryptToHexStringAsync method](#encryptToHexStringAsync-method) + - [Encrypting Data](#encrypting-data) + - [Decrypting Data](#decrypting-data) + - [EncryptToBase64StringAsync method](#encryptToBase64StringAsync-method) + - [Example](#example) + - [EncryptionData Object](#encryptiondata-object) + - [Cipher Modes](#cipher-modes) +- [Contributing](#contributing) + +## Usage + +### EncryptToHexStringAsync method + +#### Encrypting Data + +To encrypt data using the AES algorithm in this library, you first need to decide which method you want to use. +The `EncryptToHexStringAsync` method returns a hexadecimal string, while `EncryptToBase64StringAsync` returns a Base64 string. +Follow the steps below to use `EncryptToHexStringAsync`: + +1. **Generate an IV Key:** Use the `KeyGenerators.GenerateHexadecimalIVKey()` method to create an Initialization Vector (IV) key. The IV is crucial for secure encryption. + +2. **Generate a Secret Key:** Call `KeyGenerators.GenerateAesSecretKey(128)` to generate a secret key with the desired bit size. Supported bit sizes are 128, 192, or 256. Any other value will result in an exception. + +3. **Create an EncryptionParameters Model:** Construct an `EncryptionParameters` model, providing the data to be encrypted, IV, and secret key. + +4. **Call EncryptToHexStringAsync:** Invoke the `Aes.EncryptToHexStringAsync` method with the `EncryptionParameters` model to encrypt the data. Check for errors in the `Errors` property of the returned `EncryptionData` object. + +#### Decrypting Data + +To decrypt data encrypted with AES, follow these steps: + +1. **Create a DecryptionParameters Model:** Build a `DecryptionParameters` model, providing the encrypted data, IV, and secret key used during encryption. + +2. **Call DecryptFromHexStringAsync:** Use the `Aes.DecryptFromHexStringAsync` method with the `DecryptionParameters` model to decrypt the data. Ensure that the provided IV and secret key match those used during encryption. + + + +### EncryptToBase64StringAsync method +To use the EncryptToBase64StringAsync method for encryption, follow these steps: + +Generate an Initialization Vector (IV) using the KeyGenerators.GenerateBase64IVKey() method. +Generate a secret key by calling the KeyGenerators.GenerateAesSecretKey(256) method. The parameter for this method accepts the following values: 128, 192, 256. Any value aside from these throws an exception with the message "Invalid key size. Supported sizes are 128, 192, or 256 bits." +To encrypt the data, provide the EncryptionParameters model to the EncryptToBase64StringAsync method, along with an optional cipher mode. The cipher mode defaults to CBC if not specified. + + +## Example + +```csharp +using SafeCrypt.AES; +using SafeCrypt.Helpers; +using SafeCrypt.Models; + +// Using the EncryptToHexStringAsync and DecryptFromHexStringAsync methods + +var aesIv = KeyGenerators.GenerateHexadecimalIVKey(); +var secret = KeyGenerators.GenerateAesSecretKey(256); + +var dataToEncrypt = "Hello World"; + +var data = new EncryptionParameters +{ + Data = dataToEncrypt, + IV = aesIv, + SecretKey = secret +}; + +Console.WriteLine($"Hex Encryption Started"); + +Console.WriteLine(); +Console.WriteLine(); + +var encryptionResult = await Aes.EncryptToHexStringAsync(data); + +if (encryptionResult.Errors.Count > 0) +{ + // List errors here +} + +Console.WriteLine($"Hex Encrypted data: {encryptionResult.EncryptedData}"); +Console.WriteLine($"IV key: {encryptionResult.Iv}"); +Console.WriteLine($"Secret key: {encryptionResult.SecretKey}"); + +Console.WriteLine(); +Console.WriteLine(); + +Console.WriteLine($"Hex Decryption Started"); + +// Perform decryption using the same IV and secret +var decryptionResult = await Aes.DecryptFromHexStringAsync(new DecryptionParameters +{ + Data = encryptionResult.EncryptedData, + IV = aesIv, + SecretKey = secret +}); + +Console.WriteLine($"Hex Decrypted data: {decryptionResult.DecryptedData}"); +Console.WriteLine($"IV key: {decryptionResult.Iv}"); +Console.WriteLine($"Secret key: {decryptionResult.SecretKey}"); + + +// Using the EncryptToBase64StringAsync and DecryptFromBase64StringAsync methods + +var base64AesIv = KeyGenerators.GenerateBase64IVKey(); + +var base64dataToEncrypt = new EncryptionParameters +{ + Data = dataToEncrypt, + IV = base64AesIv, + SecretKey = secret +}; + +Console.WriteLine(); +Console.WriteLine(); + + +Console.WriteLine($"Base64 Encryption Started"); + +Console.WriteLine(); +Console.WriteLine(); + +var encryptedResult = await Aes.EncryptToBase64StringAsync(base64dataToEncrypt); +Console.WriteLine($"Base64 Encrypted data: {encryptedResult.EncryptedData}"); +Console.WriteLine($"IV key: {encryptedResult.Iv}"); +Console.WriteLine($"Secret key: {encryptedResult.SecretKey}"); + + +Console.WriteLine(); +Console.WriteLine(); + +Console.WriteLine($"Base64 Decryption Started"); + +var decryptionResponse = await Aes.DecryptFromBase64StringAsync(new DecryptionParameters +{ + Data = encryptedResult.EncryptedData, + IV = base64AesIv, + SecretKey = secret +}); + +Console.WriteLine($"Base64 Decrypted data: {decryptionResponse.DecryptedData}"); +Console.WriteLine($"IV key: {decryptionResponse.Iv}"); +Console.WriteLine($"Secret key: {decryptionResponse.SecretKey}"); +``` + +## EncryptionData Object + +The Encryption methods returns an `EncryptionData` object with the following properties: + +- `EncryptedData`: Holds the encrypted data as a hexadecimal string. +- `Iv`: The Initialization Vector used for encryption. +- `SecretKey`: The secret key used for encryption. +- `HasError`: If an error occurs during encryption, this property is set to true. +- `Errors`: A list of all errors that occurred during encryption. + +## Cipher Modes + +By default, the methods uses Cipher Block Chaining (CBC) mode for both encryption and decryption. +If you change the mode during encryption, provide the same mode during decryption. + +## Contributing + +Contributions to the SafeCrypt library are welcome! Follow the contribution guidelines and feel free to open issues or submit pull requests. \ No newline at end of file From 8475f8ecb5a0c5034e3882a130a833145a242667 Mon Sep 17 00:00:00 2001 From: Raphael Anyanwu Date: Tue, 5 Mar 2024 13:23:16 +0100 Subject: [PATCH 04/20] update ConvertKeysToBytes xml comment --- src/SafeCrypt.Lib/Helpers/Converters.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SafeCrypt.Lib/Helpers/Converters.cs b/src/SafeCrypt.Lib/Helpers/Converters.cs index d254060..0fff245 100644 --- a/src/SafeCrypt.Lib/Helpers/Converters.cs +++ b/src/SafeCrypt.Lib/Helpers/Converters.cs @@ -58,7 +58,7 @@ public static string ConvertToHexString(this string input) } /// - /// Converts a string to bytes and validates the resulting byte array. + /// Converts a string to byte array. /// /// The input string to convert. /// The byte array representation of the input string if valid; otherwise, null. From 4ce7068f2fda26240ad1603811684aab2cc164a1 Mon Sep 17 00:00:00 2001 From: Raphael Anyanwu Date: Tue, 5 Mar 2024 13:23:39 +0100 Subject: [PATCH 05/20] add GenerateBase64IVKey method --- src/SafeCrypt.Lib/Helpers/KeyGenerators.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/SafeCrypt.Lib/Helpers/KeyGenerators.cs b/src/SafeCrypt.Lib/Helpers/KeyGenerators.cs index 3625465..ef1d5f6 100644 --- a/src/SafeCrypt.Lib/Helpers/KeyGenerators.cs +++ b/src/SafeCrypt.Lib/Helpers/KeyGenerators.cs @@ -42,12 +42,18 @@ public static byte[] GenerateRandomIVKeyAsBytes(int length) /// . Any hyphens in the resulting string are removed /// using . /// - public static string GenerateRandomIVKeyAsString() + public static string GenerateHexadecimalIVKey() { byte[] randomBytes = GenerateRandomIVKeyAsBytes(16); return BitConverter.ToString(randomBytes).Replace("-", ""); } + public static string GenerateBase64IVKey() + { + byte[] randomBytes = GenerateRandomIVKeyAsBytes(16); + return Convert.ToBase64String(randomBytes); + } + /// /// Generates a valid AES secret key with the specified key size. /// From 64e50b1929089bdd476e5bcd51cc947c2362a9d0 Mon Sep 17 00:00:00 2001 From: Raphael Anyanwu Date: Tue, 5 Mar 2024 13:25:07 +0100 Subject: [PATCH 06/20] update AesUsage class to use updated methods --- src/SafeCrypt.Test/Usage/AesUsage.cs | 93 +++++++++++++++++++++------- 1 file changed, 69 insertions(+), 24 deletions(-) diff --git a/src/SafeCrypt.Test/Usage/AesUsage.cs b/src/SafeCrypt.Test/Usage/AesUsage.cs index 6b83c1f..db13764 100644 --- a/src/SafeCrypt.Test/Usage/AesUsage.cs +++ b/src/SafeCrypt.Test/Usage/AesUsage.cs @@ -1,4 +1,5 @@ using SafeCrypt.AES; +using SafeCrypt.Helpers; using SafeCrypt.Models; namespace SafeCrypt.App.Usage; @@ -7,42 +8,86 @@ internal static class AesUsage { internal static async void Execute() { - Console.WriteLine("------- AES Test Started -------"); + //Console.WriteLine("------- AES Test Started -------"); - var dataToEncrypt = "Data to Encrypt"; - var secret = "hghjuytsdfraestwsgtere=="; + var aesIv = KeyGenerators.GenerateHexadecimalIVKey(); + var secret = KeyGenerators.GenerateAesSecretKey(256); + var dataToEncrypt = "Hello World"; - // Encryption process - // this method generates a random IV key for the encryption process - // the IV is returned in the response with other properties - var response = await Aes.EncryptToBase64StringAsync(dataToEncrypt, secret); + var data = new EncryptionParameters + { + Data = dataToEncrypt, + IV = aesIv, + SecretKey = secret + }; + + Console.WriteLine($"Hex Encryption Started"); + Console.WriteLine(); + Console.WriteLine(); + var encryptionResult = await Aes.EncryptToHexStringAsync(data); - Console.WriteLine("............Encryption Started............"); + if (encryptionResult.Errors.Count > 0) + { + // List errors here + } - Console.WriteLine($"Encrypted data: {response.EncryptedData}"); - Console.WriteLine($"IV key: {response.Iv}"); - Console.WriteLine($"Secret key: {response.SecretKey}"); + Console.WriteLine($"Hex Encrypted data: {encryptionResult.EncryptedData}"); + Console.WriteLine($"IV key: {encryptionResult.Iv}"); + Console.WriteLine($"Secret key: {encryptionResult.SecretKey}"); Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine($"Hex Decryption Started"); + // Perform decryption using the same IV and secret + var decryptionResult = await Aes.DecryptFromHexStringAsync(new DecryptionParameters + { + Data = encryptionResult.EncryptedData, + IV = aesIv, + SecretKey = secret + }); + + Console.WriteLine($"Hex Decrypted data: {decryptionResult.DecryptedData}"); + Console.WriteLine($"IV key: {decryptionResult.Iv}"); + Console.WriteLine($"Secret key: {decryptionResult.SecretKey}"); + + // Using the EncryptToBase64StringAsync and DecryptFromBase64StringAsync methods + + var base64AesIv = KeyGenerators.GenerateBase64IVKey(); - // Decryption process - var decryptorParam = new DecryptionParameters + var base64dataToEncrypt = new EncryptionParameters { - IV = response.Iv, - SecretKey = secret, - Data = response.EncryptedData + Data = dataToEncrypt, + IV = base64AesIv, + SecretKey = secret }; - var decryptionData = await Aes.DecryptFromBase64StringAsync(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(); + Console.WriteLine(); + Console.WriteLine($"Base64 Encryption Started"); + Console.WriteLine(); + Console.WriteLine(); + var encryptedResult = await Aes.EncryptToBase64StringAsync(base64dataToEncrypt); + Console.WriteLine($"Base64 Encrypted data: {encryptedResult.EncryptedData}"); + Console.WriteLine($"IV key: {encryptedResult.Iv}"); + Console.WriteLine($"Secret key: {encryptedResult.SecretKey}"); + Console.WriteLine(); + Console.WriteLine(); + + Console.WriteLine($"Base64 Decryption Started"); + + + var decryptionResponse = await Aes.DecryptFromBase64StringAsync(new DecryptionParameters + { + Data = encryptedResult.EncryptedData, + IV = base64AesIv, + SecretKey = secret + }); + + Console.WriteLine($"Base64 Decrypted data: {decryptionResponse.DecryptedData}"); + Console.WriteLine($"IV key: {decryptionResponse.Iv}"); + Console.WriteLine($"Secret key: {decryptionResponse.SecretKey}"); - Console.WriteLine("------- AES Test Ended -------"); + //Console.WriteLine("------- AES Test Ended -------"); } } From 21d500eae83a49e33eafe43463b1b90ececcbc89 Mon Sep 17 00:00:00 2001 From: Raphael Anyanwu Date: Tue, 5 Mar 2024 13:26:15 +0100 Subject: [PATCH 07/20] add readline command to program class --- src/SafeCrypt.Test/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SafeCrypt.Test/Program.cs b/src/SafeCrypt.Test/Program.cs index 54c6d28..ec52c9d 100644 --- a/src/SafeCrypt.Test/Program.cs +++ b/src/SafeCrypt.Test/Program.cs @@ -5,4 +5,4 @@ AesUsage.Execute(); -Console.ReadLine(); +Console.ReadLine(); \ No newline at end of file From 5716c9f969f138b26819e548e0f84ced0e25b700 Mon Sep 17 00:00:00 2001 From: Raphael Anyanwu Date: Tue, 5 Mar 2024 13:38:10 +0100 Subject: [PATCH 08/20] update readme doc --- README.md | 77 ++----------------------------------------------------- 1 file changed, 2 insertions(+), 75 deletions(-) diff --git a/README.md b/README.md index 48e9659..1d71a14 100644 --- a/README.md +++ b/README.md @@ -36,82 +36,9 @@ Now, you can reference the SafeCrypt library in your C# project. ## Aes To use AES encryption in your C# application, access the static Aes class directly. -Call the provided methods; Here's a simple example: - -```csharp -using SafeCrypt.AES; -using SafeCrypt.Models; - -class Program -{ - static async Task Main() - { - - var encryptedData = await Aes.EncryptToBase64StringAsync("Hello, World!", "gdjdtsraewsuteastwerse==" - - Console.WriteLine($"Encrypted Data: {encryptedData.EncryptedData}"); - Console.WriteLine($"Initialization Vector: {encryptedData.Iv}"); - - var parameterToDecrypt = new DecryptionParameters - { - DataToDecrypt = encryptedData.EncryptedData, - SecretKey = encryptedData.SecretKey, - IV = encryptedData.IV - - }; - - var data = await Aes.DecryptFromBase64StringAsync(parameterToDecrypt); - - Console.WriteLine($"Decrypted Data: {data.DecryptedData}"); - Console.WriteLine($"Initialization Vector: {data.Iv}"); - } -} - - -------------------------------------------------------------------------------------------------------- - -using SafeCrypt.AES; -using SafeCrypt.Models; - -class Program -{ - static async Task Main() - { - var dataToEncrypt = "Data to Encrypt"; - - var iv = "gyrthusdgythisdg"; - var secret = "hghjuytsdfraestwsgtere=="; - - var encryptionParam = new EncryptionParameters - { - DataToEncrypt = dataToEncrypt, - IV = iv, - SecretKey = secret - }; - - - var response = await Aes.EncryptToBase64StringAsync(encryptionParam.DataToEncrypt, secret); - - Console.WriteLine(response.EncryptedData); - Console.WriteLine(response.Iv); - Console.WriteLine(response.SecretKey); - - var decryptorParam = new DecryptionParameters - { - IV = response.Iv, - SecretKey = secret, - DataToDecrypt = response.EncryptedData - }; - - var decryptionData = await Aes.DecryptFromBase64StringAsync(decryptorParam); - - Console.WriteLine(decryptionData.DecryptedData); - Console.WriteLine(decryptionData.Iv); - Console.WriteLine(decryptionData.SecretKey); - } -} -``` +Call the provided methods; +Check the [Aes.md](doc/Aes.md) documentation for guidance. ## Rsa This library provides a straightforward implementation of RSA encryption and decryption in C# using the .NET `RSACryptoServiceProvider`. From ef099e7c5ce53f04e91ba79f5b75804034454307 Mon Sep 17 00:00:00 2001 From: Raphael Anyanwu Date: Tue, 5 Mar 2024 13:38:55 +0100 Subject: [PATCH 09/20] update csproj file with latest deployment metadata --- src/SafeCrypt.Lib/SafeCrypt.csproj | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/SafeCrypt.Lib/SafeCrypt.csproj b/src/SafeCrypt.Lib/SafeCrypt.csproj index 2368bc6..9908d08 100644 --- a/src/SafeCrypt.Lib/SafeCrypt.csproj +++ b/src/SafeCrypt.Lib/SafeCrypt.csproj @@ -6,7 +6,7 @@ SafeCrypt - Simple Encryption Library for C# selfmade NextGen - This C# library provides methods for encrypting and decrypting data using the Advanced Encryption Standard (AES) algorithm, and more. It offers a simple interface for users to encrypt and decrypt data with ease. + The SafeCrypt library provides a set of methods for encrypting and decrypting data using various encryption algorithms, including the Advanced Encryption Standard (AES) and RSA (Rivest–Shamir–Adleman). It is designed to be easy to use and can be integrated into C# applications that require secure data transmission or storage. Raphael Anyanwu https://github.com/selfmadecode/SafeCrypt https://github.com/selfmadecode/SafeCrypt @@ -15,26 +15,29 @@ README.md True MitLicense.txt - SafeCrypt Library - Release Notes - Version 1.0.2 + Release Note - Version 1.2.0 -We are excited to announce the latest version of SafeCrypt (v1.0.2), featuring a significant enhancement to our encryption methods. In this release, all encryption operations are now asynchronous, providing improved performance and responsiveness. +We are excited to announce the latest version of SafeCrypt (v1.2.0), bringing a new feature, improvements, and bug fixes to enhance your experience with our encryption library. What's New: -Async Encryption and Decryption: -We have made all encryption methods asynchronous to better align with modern programming practices and enhance the overall responsiveness of SafeCrypt. -Bug Fixes +Aes Class Renamed: +We renamed the AesEncryption and AesDecryption class to Aes, and consolidate all encrypting and decrypting methods within this single static class. This means you can now directly access the class without the need for instantiation. -No bug fixes in this release. +Introduction of RSACryptoServiceProvider Algorithm: +We have introduced the RSACryptoServiceProvider algorithm, allowing users to choose the encryption method that best suits their specific requirements. + +Bug Fixes for Aes: +We have addressed and resolved several bugs in the Aes implementation. Upgrade Command: -dotnet add package SafeCrypt --version 1.0.2 +dotnet add package SafeCrypt --version 1.2.0 Feedback and Contributions: We appreciate your feedback and contributions! If you encounter any issues or have suggestions, please create an issue on GitHub: https://github.com/selfmadecode/SafeCrypt/issues Thank you for using the SafeCrypt Library! - 1.0.2 + 1.2.0 From 15cba009955a69e813e96705d1243a6b3c7dbc29 Mon Sep 17 00:00:00 2001 From: Raphael Anyanwu Date: Tue, 5 Mar 2024 13:53:21 +0100 Subject: [PATCH 10/20] clean aes readme file --- doc/Aes.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/doc/Aes.md b/doc/Aes.md index bb7da1b..4659f71 100644 --- a/doc/Aes.md +++ b/doc/Aes.md @@ -1,8 +1,3 @@ -what is secret, what is the length -what is IV, what is the lenght, IV as base 64, IV as hex -how to generate default IV with the package - - # SafeCrypt AES Encryption and Decryption ## Overview From f4e4482d692caac96351ea1a31e61624809e94d6 Mon Sep 17 00:00:00 2001 From: Raphael Anyanwu Date: Wed, 6 Mar 2024 09:44:20 +0100 Subject: [PATCH 11/20] add unit test project --- SafeCrypt.sln | 10 ++++++++ .../SafeCrypt.UnitTests.csproj | 23 +++++++++++++++++++ src/SafeCrypt.UnitTests/UnitTest1.cs | 11 +++++++++ 3 files changed, 44 insertions(+) create mode 100644 src/SafeCrypt.UnitTests/SafeCrypt.UnitTests.csproj create mode 100644 src/SafeCrypt.UnitTests/UnitTest1.cs diff --git a/SafeCrypt.sln b/SafeCrypt.sln index c639949..b99b140 100644 --- a/SafeCrypt.sln +++ b/SafeCrypt.sln @@ -13,6 +13,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SafeCrypt", "src\SafeCrypt. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SafeCrypt.App", "src\SafeCrypt.Test\SafeCrypt.App.csproj", "{DAD7FFA3-AABC-47FF-BA79-0C9531BFBBE6}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SafeCrypt.UnitTests", "SafeCrypt.UnitTests", "{5FC8B106-513E-4B2D-A2C0-2D5B5B76947C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SafeCrypt.UnitTests", "src\SafeCrypt.UnitTests\SafeCrypt.UnitTests.csproj", "{5A43627C-68E1-44E3-9866-DE15FE976392}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -27,6 +31,10 @@ Global {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 + {5A43627C-68E1-44E3-9866-DE15FE976392}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5A43627C-68E1-44E3-9866-DE15FE976392}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5A43627C-68E1-44E3-9866-DE15FE976392}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5A43627C-68E1-44E3-9866-DE15FE976392}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -36,6 +44,8 @@ Global {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} + {5FC8B106-513E-4B2D-A2C0-2D5B5B76947C} = {0B7C0C60-9850-4554-AF85-86C0378B6B16} + {5A43627C-68E1-44E3-9866-DE15FE976392} = {5FC8B106-513E-4B2D-A2C0-2D5B5B76947C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {639A4359-2BA4-4F71-9EBF-D6EAB68C84CB} diff --git a/src/SafeCrypt.UnitTests/SafeCrypt.UnitTests.csproj b/src/SafeCrypt.UnitTests/SafeCrypt.UnitTests.csproj new file mode 100644 index 0000000..50f1ad6 --- /dev/null +++ b/src/SafeCrypt.UnitTests/SafeCrypt.UnitTests.csproj @@ -0,0 +1,23 @@ + + + + net6.0 + enable + enable + + false + true + + + + + + + + + + + + + + diff --git a/src/SafeCrypt.UnitTests/UnitTest1.cs b/src/SafeCrypt.UnitTests/UnitTest1.cs new file mode 100644 index 0000000..dafd312 --- /dev/null +++ b/src/SafeCrypt.UnitTests/UnitTest1.cs @@ -0,0 +1,11 @@ +namespace SafeCrypt.UnitTests +{ + public class UnitTest1 + { + [Fact] + public void Test1() + { + + } + } +} \ No newline at end of file From e0a8bc4bf4161fce3a3700794519877d4dbf7295 Mon Sep 17 00:00:00 2001 From: Raphael Anyanwu Date: Wed, 6 Mar 2024 09:49:51 +0100 Subject: [PATCH 12/20] remove sample test class add aes encrytion test class --- src/SafeCrypt.UnitTests/Aes/Encryption.cs | 10 ++++++++++ src/SafeCrypt.UnitTests/UnitTest1.cs | 11 ----------- 2 files changed, 10 insertions(+), 11 deletions(-) create mode 100644 src/SafeCrypt.UnitTests/Aes/Encryption.cs delete mode 100644 src/SafeCrypt.UnitTests/UnitTest1.cs diff --git a/src/SafeCrypt.UnitTests/Aes/Encryption.cs b/src/SafeCrypt.UnitTests/Aes/Encryption.cs new file mode 100644 index 0000000..f7e518b --- /dev/null +++ b/src/SafeCrypt.UnitTests/Aes/Encryption.cs @@ -0,0 +1,10 @@ +namespace SafeCrypt.UnitTests.Aes; + +public class Encryption +{ + [Fact] + public void Test1() + { + + } +} diff --git a/src/SafeCrypt.UnitTests/UnitTest1.cs b/src/SafeCrypt.UnitTests/UnitTest1.cs deleted file mode 100644 index dafd312..0000000 --- a/src/SafeCrypt.UnitTests/UnitTest1.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace SafeCrypt.UnitTests -{ - public class UnitTest1 - { - [Fact] - public void Test1() - { - - } - } -} \ No newline at end of file From 1963ca45c2562a01c592da2e3b3d5678691d1fa4 Mon Sep 17 00:00:00 2001 From: Raphael Anyanwu Date: Wed, 6 Mar 2024 11:35:50 +0100 Subject: [PATCH 13/20] changed void to task in Aes usgae class --- src/SafeCrypt.Test/Usage/AesUsage.cs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/SafeCrypt.Test/Usage/AesUsage.cs b/src/SafeCrypt.Test/Usage/AesUsage.cs index db13764..35aa0fc 100644 --- a/src/SafeCrypt.Test/Usage/AesUsage.cs +++ b/src/SafeCrypt.Test/Usage/AesUsage.cs @@ -6,9 +6,9 @@ namespace SafeCrypt.App.Usage; internal static class AesUsage { - internal static async void Execute() + internal static async Task Execute() { - //Console.WriteLine("------- AES Test Started -------"); + Console.WriteLine("------- AES Test Started -------"); var aesIv = KeyGenerators.GenerateHexadecimalIVKey(); var secret = KeyGenerators.GenerateAesSecretKey(256); @@ -21,7 +21,7 @@ internal static async void Execute() SecretKey = secret }; - Console.WriteLine($"Hex Encryption Started"); + Console.WriteLine($"AES Hex Encryption Started"); Console.WriteLine(); Console.WriteLine(); var encryptionResult = await Aes.EncryptToHexStringAsync(data); @@ -37,7 +37,8 @@ internal static async void Execute() Console.WriteLine(); Console.WriteLine(); - Console.WriteLine($"Hex Decryption Started"); + + Console.WriteLine($"AES Hex Decryption Started"); // Perform decryption using the same IV and secret var decryptionResult = await Aes.DecryptFromHexStringAsync(new DecryptionParameters { @@ -63,17 +64,20 @@ internal static async void Execute() Console.WriteLine(); Console.WriteLine(); - Console.WriteLine($"Base64 Encryption Started"); + Console.WriteLine($"AES Base64 Encryption Started"); Console.WriteLine(); Console.WriteLine(); + var encryptedResult = await Aes.EncryptToBase64StringAsync(base64dataToEncrypt); + Console.WriteLine($"Base64 Encrypted data: {encryptedResult.EncryptedData}"); + Console.WriteLine($"IV key: {encryptedResult.Iv}"); Console.WriteLine($"Secret key: {encryptedResult.SecretKey}"); Console.WriteLine(); Console.WriteLine(); - Console.WriteLine($"Base64 Decryption Started"); + Console.WriteLine($"AES Base64 Decryption Started"); var decryptionResponse = await Aes.DecryptFromBase64StringAsync(new DecryptionParameters @@ -87,7 +91,6 @@ internal static async void Execute() Console.WriteLine($"IV key: {decryptionResponse.Iv}"); Console.WriteLine($"Secret key: {decryptionResponse.SecretKey}"); - //Console.WriteLine("------- AES Test Ended -------"); - + Console.WriteLine("------- AES Test Ended -------"); } } From 4afcf5a6e26aa4b0d0b17bc37eae1d94683d52ef Mon Sep 17 00:00:00 2001 From: Raphael Anyanwu Date: Wed, 6 Mar 2024 11:36:08 +0100 Subject: [PATCH 14/20] changed void to task in Rsa usgae class --- src/SafeCrypt.Test/Usage/RsaUsage.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SafeCrypt.Test/Usage/RsaUsage.cs b/src/SafeCrypt.Test/Usage/RsaUsage.cs index f14488c..66996b7 100644 --- a/src/SafeCrypt.Test/Usage/RsaUsage.cs +++ b/src/SafeCrypt.Test/Usage/RsaUsage.cs @@ -6,7 +6,7 @@ namespace SafeCrypt.App.Usage; internal static class RsaUsage { - internal static async void Execute() + internal static async Task Execute() { Console.WriteLine("------- RSA Test Started -------"); From 077e6db4d92b4d0d0ce776bb4c2ce08c3a6f7246 Mon Sep 17 00:00:00 2001 From: Raphael Anyanwu Date: Wed, 6 Mar 2024 11:36:50 +0100 Subject: [PATCH 15/20] await usage classes in main --- src/SafeCrypt.Test/Program.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SafeCrypt.Test/Program.cs b/src/SafeCrypt.Test/Program.cs index ec52c9d..e9abc73 100644 --- a/src/SafeCrypt.Test/Program.cs +++ b/src/SafeCrypt.Test/Program.cs @@ -1,8 +1,8 @@ // See https://aka.ms/new-console-template for more information using SafeCrypt.App.Usage; -RsaUsage.Execute(); +await RsaUsage.Execute(); -AesUsage.Execute(); +await AesUsage.Execute(); -Console.ReadLine(); \ No newline at end of file +Console.ReadLine(); From 117489b6a9d4b70373e5f09e6ebaaea88c5dcf15 Mon Sep 17 00:00:00 2001 From: Raphael Anyanwu Date: Wed, 6 Mar 2024 11:37:30 +0100 Subject: [PATCH 16/20] rename Aes folder to AesTests --- src/SafeCrypt.UnitTests/Aes/Encryption.cs | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 src/SafeCrypt.UnitTests/Aes/Encryption.cs diff --git a/src/SafeCrypt.UnitTests/Aes/Encryption.cs b/src/SafeCrypt.UnitTests/Aes/Encryption.cs deleted file mode 100644 index f7e518b..0000000 --- a/src/SafeCrypt.UnitTests/Aes/Encryption.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace SafeCrypt.UnitTests.Aes; - -public class Encryption -{ - [Fact] - public void Test1() - { - - } -} From 0e96b9ff024cf5da0452d3e4f1ae157617a6f1f5 Mon Sep 17 00:00:00 2001 From: Raphael Anyanwu Date: Wed, 6 Mar 2024 11:38:46 +0100 Subject: [PATCH 17/20] add safecrypt package reference in unit test project --- src/SafeCrypt.UnitTests/SafeCrypt.UnitTests.csproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SafeCrypt.UnitTests/SafeCrypt.UnitTests.csproj b/src/SafeCrypt.UnitTests/SafeCrypt.UnitTests.csproj index 50f1ad6..1d8113d 100644 --- a/src/SafeCrypt.UnitTests/SafeCrypt.UnitTests.csproj +++ b/src/SafeCrypt.UnitTests/SafeCrypt.UnitTests.csproj @@ -16,6 +16,10 @@ + + + + From 83842a6b8bce30decb863d4d36b84a95cb13821c Mon Sep 17 00:00:00 2001 From: Raphael Anyanwu Date: Wed, 6 Mar 2024 11:39:23 +0100 Subject: [PATCH 18/20] add test for Hex encrypt and decrypt methods --- .../AesTests/Encryption.cs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/SafeCrypt.UnitTests/AesTests/Encryption.cs diff --git a/src/SafeCrypt.UnitTests/AesTests/Encryption.cs b/src/SafeCrypt.UnitTests/AesTests/Encryption.cs new file mode 100644 index 0000000..9d99f3d --- /dev/null +++ b/src/SafeCrypt.UnitTests/AesTests/Encryption.cs @@ -0,0 +1,44 @@ +using SafeCrypt.Helpers; +using SafeCrypt.Models; +using SafeCrypt.AES; + +namespace SafeCrypt.UnitTests.AesTests; + +public class Encryption +{ + public const string Data = "Hello, World!"; + + [Fact] + public async Task EncryptToHexStringAsync_And_DecryptFromHexStringAsync_ValidParameters_ReturnsOriginalData() + { + // Arrange + var aesIv = KeyGenerators.GenerateHexadecimalIVKey(); + var secret = KeyGenerators.GenerateAesSecretKey(256); + + var encryptionParameters = new EncryptionParameters + { + Data = Data, + IV = aesIv, + SecretKey = secret + }; + + // Act + var encryptedResult = await Aes.EncryptToHexStringAsync(encryptionParameters); + var decryptedResult = await Aes.DecryptFromHexStringAsync(new DecryptionParameters + { + Data = encryptedResult.EncryptedData, + IV = aesIv, + SecretKey = secret + }); + + // Assert + Assert.NotNull(encryptedResult.EncryptedData); + Assert.Equal(Data, decryptedResult.DecryptedData); + + Assert.False(encryptedResult.HasError); + Assert.False(decryptedResult.HasError); + + Assert.Empty(encryptedResult.Errors); + Assert.Empty(decryptedResult.Errors); + } +} From fc0037643f35b7ba527f91f9026f3e5cd6f27bf7 Mon Sep 17 00:00:00 2001 From: Raphael Anyanwu Date: Wed, 6 Mar 2024 11:45:10 +0100 Subject: [PATCH 19/20] renamed test class --- .../AesTests/{Encryption.cs => EncryptionDecryption.cs} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/SafeCrypt.UnitTests/AesTests/{Encryption.cs => EncryptionDecryption.cs} (97%) diff --git a/src/SafeCrypt.UnitTests/AesTests/Encryption.cs b/src/SafeCrypt.UnitTests/AesTests/EncryptionDecryption.cs similarity index 97% rename from src/SafeCrypt.UnitTests/AesTests/Encryption.cs rename to src/SafeCrypt.UnitTests/AesTests/EncryptionDecryption.cs index 9d99f3d..3e33e0c 100644 --- a/src/SafeCrypt.UnitTests/AesTests/Encryption.cs +++ b/src/SafeCrypt.UnitTests/AesTests/EncryptionDecryption.cs @@ -4,7 +4,7 @@ namespace SafeCrypt.UnitTests.AesTests; -public class Encryption +public class EncryptionDecryption { public const string Data = "Hello, World!"; From 8e8ef52a541042b595289a06c889bd03370f9f1c Mon Sep 17 00:00:00 2001 From: Raphael Anyanwu Date: Wed, 6 Mar 2024 12:01:43 +0100 Subject: [PATCH 20/20] test encrypt and decrypt test for base 64 string --- .../AesTests/EncryptionDecryption.cs | 54 +++++++++++++++---- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/src/SafeCrypt.UnitTests/AesTests/EncryptionDecryption.cs b/src/SafeCrypt.UnitTests/AesTests/EncryptionDecryption.cs index 3e33e0c..7e03865 100644 --- a/src/SafeCrypt.UnitTests/AesTests/EncryptionDecryption.cs +++ b/src/SafeCrypt.UnitTests/AesTests/EncryptionDecryption.cs @@ -1,6 +1,7 @@ using SafeCrypt.Helpers; using SafeCrypt.Models; using SafeCrypt.AES; +using SafeCrypt.RsaEncryption.Models; namespace SafeCrypt.UnitTests.AesTests; @@ -23,22 +24,57 @@ public async Task EncryptToHexStringAsync_And_DecryptFromHexStringAsync_ValidPar }; // Act - var encryptedResult = await Aes.EncryptToHexStringAsync(encryptionParameters); - var decryptedResult = await Aes.DecryptFromHexStringAsync(new DecryptionParameters + var encryptionResult = await Aes.EncryptToHexStringAsync(encryptionParameters); + Assert.False(encryptionResult.HasError); + + var decryptionResult = await Aes.DecryptFromHexStringAsync(new DecryptionParameters { - Data = encryptedResult.EncryptedData, + Data = encryptionResult.EncryptedData, IV = aesIv, SecretKey = secret }); // Assert - Assert.NotNull(encryptedResult.EncryptedData); - Assert.Equal(Data, decryptedResult.DecryptedData); + Assert.NotNull(encryptionResult.EncryptedData); + Assert.Equal(Data, decryptionResult.DecryptedData); - Assert.False(encryptedResult.HasError); - Assert.False(decryptedResult.HasError); + Assert.False(encryptionResult.HasError); + Assert.False(decryptionResult.HasError); - Assert.Empty(encryptedResult.Errors); - Assert.Empty(decryptedResult.Errors); + Assert.Empty(encryptionResult.Errors); + Assert.Empty(decryptionResult.Errors); + } + + [Theory] + [InlineData(Data)] + public async Task EncryptToBase64StringAndDecryptAsync_DecryptedDataMatchesOriginalData(string originalData) + { + // Arrange + var aesIv = KeyGenerators.GenerateBase64IVKey(); + var secret = KeyGenerators.GenerateAesSecretKey(256); + + var encryptionParameters = new EncryptionParameters + { + Data = originalData, + IV = aesIv, + SecretKey = secret + }; + + // Act + var encryptionResult = await Aes.EncryptToBase64StringAsync(encryptionParameters); + Assert.False(encryptionResult.HasError); + + var decryptionParameters = new DecryptionParameters + { + Data = encryptionResult.EncryptedData, + IV = aesIv, + SecretKey = secret + }; + + var decryptionResult = await Aes.DecryptFromBase64StringAsync(decryptionParameters); + Assert.False(decryptionResult.HasError); + + // Assert + Assert.Equal(originalData, decryptionResult.DecryptedData); } }