Skip to content

Commit bfef3a3

Browse files
authored
Merge pull request #51 from selfmadecode/dev
feat: add rsa algorithm, change aes algorithms to static methods
2 parents 67445fb + de80fe6 commit bfef3a3

13 files changed

Lines changed: 517 additions & 48 deletions

File tree

README.md

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ A C# library for encryption and decryption.
44

55
## Overview
66

7-
The Encryption library provides a set of methods for encrypting and decrypting data using the Advanced Encryption Standard (AES) algorithm, and other algorithm. It is designed to be easy to use and can be integrated into C# applications that require secure data transmission or storage.
8-
7+
The SafeCrypt library provides a set of methods for encrypting and decrypting data using various encryption algorithms,
8+
including the Advanced Encryption Standard (AES) and RSA (Rivest–Shamir–Adleman).
9+
It is designed to be easy to use and can be integrated into C# applications that require secure data transmission or storage.
910
## Table of Contents
1011

1112
- [Installation](#installation)
12-
- [Usage](#usage)
13-
- [API Reference](#api-reference)
14-
- [Examples](#examples)
13+
- [AES Encryption and Decryption usage](#usage)
14+
- [RSA Encryption and Decryption usage](#rsa)
1515
- [Contributing](#contributing)
1616
- [License](#license)
1717

@@ -34,28 +34,25 @@ To use the SafeCrypt library in your C# project, follow these steps:
3434

3535
Now, you can reference the SafeCrypt library in your C# project.
3636

37-
## Basic Usage
37+
## Usage
3838

39-
To use the library in your C# application, instantiate the `AesEncryption` or `AesDecryption` class and call the provided methods. Here's a simple example:
39+
To use the AES encryption in your C# application,
40+
instantiate the `AesEncryption` or `AesDecryption` class and call the provided methods. Here's a simple example:
4041

4142
```csharp
42-
using SafeCrypt.AESDecryption;
43-
using SafeCrypt.AESEncryption;
43+
using SafeCrypt.AES;
4444
using SafeCrypt.Models;
4545

4646
class Program
4747
{
4848
static async Task Main()
4949
{
50-
var aesEncryptor = new AesEncryption();
5150

52-
var encryptedData = await aesEncryptor.EncryptToBase64StringAsync("Hello, World!", "gdjdtsraewsuteastwerse=="
51+
var encryptedData = await Aes.EncryptToBase64StringAsync("Hello, World!", "gdjdtsraewsuteastwerse=="
5352

5453
Console.WriteLine($"Encrypted Data: {encryptedData.EncryptedData}");
5554
Console.WriteLine($"Initialization Vector: {encryptedData.Iv}");
56-
57-
var aesDecryptor = new AesDecryption();
58-
55+
5956
var parameterToDecrypt = new DecryptionParameters
6057
{
6158
DataToDecrypt = encryptedData.EncryptedData,
@@ -64,7 +61,7 @@ class Program
6461

6562
};
6663

67-
var data = await aesDecryptor.DecryptFromBase64StringAsync(parameterToDecrypt)
64+
var data = await Aes.DecryptFromBase64StringAsync(parameterToDecrypt)
6865

6966
Console.WriteLine($"Decrypted Data: {data.DecryptedData}");
7067
Console.WriteLine($"Initialization Vector: {data.Iv}");
@@ -74,8 +71,7 @@ class Program
7471

7572
-------------------------------------------------------------------------------------------------------
7673

77-
using SafeCrypt.AESDecryption;
78-
using SafeCrypt.AESEncryption;
74+
using SafeCrypt.AES;
7975
using SafeCrypt.Models;
8076

8177
class Program
@@ -94,9 +90,8 @@ class Program
9490
SecretKey = secret
9591
};
9692

97-
var encryptor = new AesEncryption();
9893

99-
var response = await encryptor.EncryptToBase64StringAsync(encryptionParam.DataToEncrypt, secret);
94+
var response = await Aes.EncryptToBase64StringAsync(encryptionParam.DataToEncrypt, secret);
10095

10196
Console.WriteLine(response.EncryptedData);
10297
Console.WriteLine(response.Iv);
@@ -112,8 +107,7 @@ class Program
112107
};
113108

114109

115-
var decryptor = new AesDecryption();
116-
var decryptionData = await decryptor.DecryptFromBase64StringAsync(decryptorParam);
110+
var decryptionData = await Aes.DecryptFromBase64StringAsync(decryptorParam);
117111

118112
Console.WriteLine(decryptionData.DecryptedData);
119113
Console.WriteLine(decryptionData.Iv);
@@ -122,6 +116,14 @@ class Program
122116
}
123117
```
124118

119+
120+
## Rsa
121+
This library provides a straightforward implementation of RSA encryption and decryption in C# using the .NET `RSACryptoServiceProvider`.
122+
It includes methods for generating RSA key pairs, encrypting data with a public key, and decrypting data with a private key.
123+
124+
For more details on RSA Encryption, check the [Rsa.md](doc/Rsa.md) document.
125+
126+
125127
## Contributing
126128

127129
If you would like to contribute to the development of the SafeCrypt library, follow these steps:

doc/Rsa.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# RSA Encryption and Decryption
2+
3+
## Overview
4+
5+
This library provides a straightforward implementation of RSA encryption and decryption in C# using the .NET `RSACryptoServiceProvider`.
6+
It includes methods for generating RSA key pairs, encrypting data with a public key, and decrypting data with a private key.
7+
8+
## Table of Contents
9+
10+
- [Usage](#usage)
11+
- [Generate RSA Keys](#generate-rsa-keys)
12+
- [Encrypt and Decrypt using RSA](#encrypt-and-decrypt-using-rsa)
13+
14+
## Usage
15+
16+
### Generate RSA Keys
17+
18+
```csharp
19+
using SafeCrypt.Helpers;
20+
using SafeCrypt.RsaEncryption;
21+
22+
var rsaKeyPair = KeyGenerators.GenerateRsaKeys(2048);
23+
24+
string rsaPublicKey = rsaKeyPair.Item1;
25+
string rsaPrivateKey = rsaKeyPair.Item2;
26+
27+
Console.WriteLine($"Public Key: {rsaPublicKey}");
28+
Console.WriteLine($"Private Key: {rsaPrivateKey}");
29+
```
30+
31+
### Encrypt and Decrypt using RSA
32+
33+
```csharp
34+
using SafeCrypt.RsaEncryption;
35+
36+
// Encrypt
37+
string originalData = "Hello, RSA Encryption!";
38+
39+
var encryptionModel = new RsaEncryptionParameters
40+
{
41+
DataToEncrypt = originalData,
42+
PublicKey = rsaPublicKey,
43+
};
44+
45+
var encryptedData = await Rsa.EncryptAsync(encryptionModel);
46+
47+
Console.WriteLine($"Original Data: {originalData}");
48+
Console.WriteLine("Encrypted Data: " + BitConverter.ToString(encryptedData.EncryptedData));
49+
50+
// Convert encrypted byte array to Base64 string
51+
string encryptedDataConvertedString = Convert.ToBase64String(encryptedData.EncryptedData);
52+
53+
// Convert string back to byte array for decryption
54+
byte[] convertedBytes = Convert.FromBase64String(encryptedDataConvertedString);
55+
56+
bool arraysAreEqual = StructuralComparisons.StructuralEqualityComparer.Equals(encryptedData.EncryptedData, convertedBytes);
57+
Console.WriteLine("Original and converted byte arrays are equal: " + arraysAreEqual); // should return true
58+
59+
60+
61+
// Decrypt
62+
var decryptionModel = new RsaDecryptionParameters
63+
{
64+
DataToDecrypt = convertedBytes, // encryptedData.EncryptedData
65+
PrivateKey = rsaPrivateKey,
66+
};
67+
68+
var decryptedData = await Rsa.DecryptAsync(decryptionModel);
69+
70+
// if Error occurs during encryption
71+
if (decryptedData.Errors.Count > 0)
72+
{
73+
Console.WriteLine("Decryption Errors:");
74+
foreach (var error in decryptedData.Errors)
75+
{
76+
Console.WriteLine(error);
77+
}
78+
}
79+
else
80+
{
81+
Console.WriteLine($"Decrypted Data: {decryptedData.DecryptedData}");
82+
}
83+
84+
// Note: The return type from Rsa.EncryptAsync is `EncryptionResult`, and Rsa.DecryptAsync is `DecryptionResult`.
85+
// Both models include a list of errors encountered during encryption/decryption.
86+
87+
```
88+
## Contributing
89+
90+
Contributions are welcome! Feel free to open issues, submit pull requests, or provide feedback.

src/SafeCrypt.Lib/Encryption/AesEncryption/BaseAesEncryption.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace SafeCrypt.AesEncryption
88
{
9-
public class BaseAesEncryption
9+
public static class BaseAesEncryption
1010
{
1111
/// <summary>
1212
/// Encrypts the provided data using the Advanced Encryption Standard (AES) algorithm.

src/SafeCrypt.Lib/Encryption/AesEncryption/Decrypting.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
using System.Security.Cryptography;
66
using System.Threading.Tasks;
77

8-
namespace SafeCrypt.AESDecryption
8+
namespace SafeCrypt.AES
99
{
10-
public class AesDecryption : BaseAesEncryption
10+
public static partial class Aes
1111
{
1212
/// <summary>
1313
/// Asynchronously decrypts data from a hexadecimal string using the specified decryption parameters and cipher mode.
@@ -19,7 +19,7 @@ public class AesDecryption : BaseAesEncryption
1919
/// The task result is a <see cref="DecryptionData"/> object containing the decrypted data, IV, and secret key.
2020
/// If decryption fails, the <see cref="DecryptionData"/> object will contain error information.
2121
/// </returns>
22-
public async Task<DecryptionData> DecryptFromHexStringAsync(DecryptionParameters param, CipherMode mode = CipherMode.CBC)
22+
public static async Task<DecryptionData> DecryptFromHexStringAsync(DecryptionParameters param, CipherMode mode = CipherMode.CBC)
2323
{
2424
var responseData = new DecryptionData();
2525

@@ -55,7 +55,7 @@ public async Task<DecryptionData> DecryptFromHexStringAsync(DecryptionParameters
5555
Data = param.DataToDecrypt.HexadecimalStringToByteArray()
5656
};
5757

58-
var response = await DecryptAsync(byteEncryptionParameters, mode);
58+
var response = await BaseAesEncryption.DecryptAsync(byteEncryptionParameters, mode);
5959

6060
return new DecryptionData
6161
{
@@ -75,7 +75,7 @@ public async Task<DecryptionData> DecryptFromHexStringAsync(DecryptionParameters
7575
/// The task result is a <see cref="DecryptionData"/> object containing the decrypted data, IV, and secret key.
7676
/// If decryption fails, the <see cref="DecryptionData"/> object will contain error information.
7777
/// </returns>
78-
public async Task<DecryptionData> DecryptFromBase64StringAsync(DecryptionParameters param, CipherMode mode = CipherMode.CBC)
78+
public static async Task<DecryptionData> DecryptFromBase64StringAsync(DecryptionParameters param, CipherMode mode = CipherMode.CBC)
7979
{
8080
var responseData = new DecryptionData();
8181

@@ -103,7 +103,7 @@ public async Task<DecryptionData> DecryptFromBase64StringAsync(DecryptionParamet
103103
Data = Convert.FromBase64String(param.DataToDecrypt)
104104
};
105105

106-
var response = await DecryptAsync(byteDecryptionParameters, mode);
106+
var response = await BaseAesEncryption.DecryptAsync(byteDecryptionParameters, mode);
107107

108108
return new DecryptionData
109109
{
@@ -121,7 +121,7 @@ public async Task<DecryptionData> DecryptFromBase64StringAsync(DecryptionParamet
121121
}
122122

123123

124-
private void NullChecks(string data, string secretKey, string iv)
124+
private static void NullChecks(string data, string secretKey, string iv)
125125
{
126126
if (data == null || data.Length <= 0)
127127
throw new ArgumentNullException(nameof(data));
@@ -133,13 +133,13 @@ private void NullChecks(string data, string secretKey, string iv)
133133
throw new ArgumentNullException(nameof(iv));
134134
}
135135

136-
private (byte[], byte[]) ConvertKeysToBytesAndGetKeys(string secretKey, string iv)
136+
private static (byte[], byte[]) ConvertKeysToBytesAndGetKeys(string secretKey, string iv)
137137
{
138138

139139
return (secretKey.ConvertKeysToBytes(), iv.ConvertKeysToBytes());
140140
}
141141

142-
private void AddError(DecryptionData responseData, string error)
142+
private static void AddError(DecryptionData responseData, string error)
143143
{
144144
responseData.HasError = true;
145145
responseData.Errors.Add(error);

src/SafeCrypt.Lib/Encryption/AesEncryption/Encrypting.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
using System.Security.Cryptography;
66
using System.Threading.Tasks;
77

8-
namespace SafeCrypt.AESEncryption
8+
namespace SafeCrypt.AES
99
{
10-
public class AesEncryption : BaseAesEncryption
10+
public static partial class Aes
1111
{
1212
/// <summary>
1313
/// Asynchronously encrypts the provided data using the specified secret key and initialization vector (IV).
@@ -23,7 +23,7 @@ public class AesEncryption : BaseAesEncryption
2323
/// <param name="secretKey">The secret key used for encryption.</param>
2424
/// <param name="iv">The initialization vector used for encryption.</param>
2525
/// <returns>The encrypted data as a byte array.</returns>
26-
public async Task<EncryptionData> EncryptToHexStringAsync(EncryptionParameters param, CipherMode mode = CipherMode.CBC)
26+
public static async Task<EncryptionData> EncryptToHexStringAsync(EncryptionParameters param, CipherMode mode = CipherMode.CBC)
2727
{
2828
var responseData = new EncryptionData();
2929

@@ -52,7 +52,7 @@ public async Task<EncryptionData> EncryptToHexStringAsync(EncryptionParameters p
5252
Data = param.DataToEncrypt.ConvertToHexString().HexadecimalStringToByteArray()
5353
};
5454

55-
var response = await EncryptAsync(byteEncryptionParameters, mode);
55+
var response = await BaseAesEncryption.EncryptAsync(byteEncryptionParameters, mode);
5656

5757
return new EncryptionData
5858
{
@@ -84,7 +84,7 @@ public async Task<EncryptionData> EncryptToHexStringAsync(EncryptionParameters p
8484
/// <exception cref="FormatException">
8585
/// Thrown if the base64secretKey is not a valid Base64-encoded string.
8686
/// </exception>
87-
public async Task<EncryptionData> EncryptToBase64StringAsync(string dataToBeEncrypted, string base64secretKey, CipherMode mode = CipherMode.CBC)
87+
public static async Task<EncryptionData> EncryptToBase64StringAsync(string dataToBeEncrypted, string base64secretKey, CipherMode mode = CipherMode.CBC)
8888
{
8989
// validate is base64
9090
if (!Validators.IsBase64String(base64secretKey))
@@ -104,7 +104,7 @@ public async Task<EncryptionData> EncryptToBase64StringAsync(string dataToBeEncr
104104
Data = dataToBeEncrypted.ConvertToHexString().HexadecimalStringToByteArray()
105105
};
106106

107-
var response = await EncryptAsync(byteEncryptionParameters, mode);
107+
var response = await BaseAesEncryption.EncryptAsync(byteEncryptionParameters, mode);
108108

109109
return new EncryptionData
110110
{
@@ -114,7 +114,7 @@ public async Task<EncryptionData> EncryptToBase64StringAsync(string dataToBeEncr
114114
};
115115
}
116116

117-
private EncryptionData ValidateEncryptionParameters(EncryptionParameters param)
117+
private static EncryptionData ValidateEncryptionParameters(EncryptionParameters param)
118118
{
119119
var responseData = new EncryptionData();
120120

@@ -134,7 +134,7 @@ private EncryptionData ValidateEncryptionParameters(EncryptionParameters param)
134134
return responseData;
135135
}
136136

137-
private void NullChecks(string data, string secretKey)
137+
private static void NullChecks(string data, string secretKey)
138138
{
139139
if (data == null || data.Length <= 0)
140140
throw new ArgumentNullException(nameof(data));
@@ -143,7 +143,7 @@ private void NullChecks(string data, string secretKey)
143143
throw new ArgumentNullException(nameof(secretKey));
144144
}
145145

146-
private void AddError(EncryptionData responseData, string error)
146+
private static void AddError(EncryptionData responseData, string error)
147147
{
148148
responseData.HasError = true;
149149
responseData.Errors.Add(error);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System.ComponentModel.DataAnnotations;
2+
3+
namespace SafeCrypt.RsaEncryption
4+
{
5+
public sealed class RsaEncryptionParameters : IEncryptionData
6+
{
7+
/// <summary>
8+
/// Gets or sets the public key for RSA encryption.
9+
/// </summary>
10+
[Required]
11+
public string PublicKey { get; set; }
12+
13+
/// <summary>
14+
/// Gets or sets the data to be encrypted using RSA.
15+
/// </summary>
16+
[Required]
17+
public string DataToEncrypt { get; set; }
18+
}
19+
20+
public sealed class RsaDecryptionParameters
21+
{
22+
/// <summary>
23+
/// Gets or sets the public key for RSA encryption.
24+
/// </summary>
25+
[Required]
26+
public string PrivateKey { get; set; }
27+
28+
/// <summary>
29+
/// Gets or sets the data to be encrypted using RSA.
30+
/// </summary>
31+
[Required]
32+
public byte[] DataToDecrypt { get; set; }
33+
}
34+
}

0 commit comments

Comments
 (0)