Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 6 additions & 83 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 (RivestShamirAdleman).
including the Advanced Encryption Standard (AES) and RSA (RivestShamirAdleman).
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)
Expand All @@ -34,88 +34,11 @@ 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:

```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);
}
}
```
## Aes
To use AES encryption in your C# application, access the static Aes class directly.
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`.
Expand Down
10 changes: 10 additions & 0 deletions SafeCrypt.sln
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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}
Expand Down
172 changes: 172 additions & 0 deletions doc/Aes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# 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.
26 changes: 17 additions & 9 deletions src/SafeCrypt.Lib/Encryption/AesEncryption/Encrypting.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,33 +84,41 @@ public static async Task<EncryptionData> EncryptToHexStringAsync(EncryptionParam
/// <exception cref="FormatException">
/// Thrown if the base64secretKey is not a valid Base64-encoded string.
/// </exception>
public static async Task<EncryptionData> EncryptToBase64StringAsync(string dataToBeEncrypted, string base64secretKey, CipherMode mode = CipherMode.CBC)
public static async Task<EncryptionData> 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);

return new EncryptionData
{
EncryptedData = Convert.ToBase64String(response),
Iv = Convert.ToBase64String(aesIv),
SecretKey = base64secretKey
Iv = param.IV,
SecretKey = param.SecretKey
};
}

Expand Down
2 changes: 1 addition & 1 deletion src/SafeCrypt.Lib/Helpers/Converters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public static string ConvertToHexString(this string input)
}

/// <summary>
/// Converts a string to bytes and validates the resulting byte array.
/// Converts a string to byte array.
/// </summary>
/// <param name="input">The input string to convert.</param>
/// <returns>The byte array representation of the input string if valid; otherwise, null.</returns>
Expand Down
8 changes: 7 additions & 1 deletion src/SafeCrypt.Lib/Helpers/KeyGenerators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,18 @@ public static byte[] GenerateRandomIVKeyAsBytes(int length)
/// <see cref="BitConverter.ToString"/>. Any hyphens in the resulting string are removed
/// using <see cref="string.Replace"/>.
/// </remarks>
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);
}

/// <summary>
/// Generates a valid AES secret key with the specified key size.
/// </summary>
Expand Down
Loading