Skip to content

Commit 48c78a2

Browse files
authored
Merge pull request #22 from selfmadecode/dev_raphael_aes
feat: add decryption and encryption methods and models
2 parents e05f28d + 8e1c018 commit 48c78a2

12 files changed

Lines changed: 493 additions & 194 deletions

SafeCrypt.sln

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio Version 16
4-
VisualStudioVersion = 16.0.33214.272
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.8.34322.80
55
MinimumVisualStudioVersion = 10.0.40219.1
6-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SafeCrypt", "SafeCrypt.csproj", "{204CA507-752E-43A6-A094-794E40ABAE1F}"
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SafeCrypt", "SafeCrypt.csproj", "{204CA507-752E-43A6-A094-794E40ABAE1F}"
7+
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "safecrypt-testapp", "..\safecrypt-testapp\safecrypt-testapp.csproj", "{76D17C56-5643-4148-A504-8D6E24D24CAD}"
79
EndProject
810
Global
911
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -15,6 +17,10 @@ Global
1517
{204CA507-752E-43A6-A094-794E40ABAE1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
1618
{204CA507-752E-43A6-A094-794E40ABAE1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
1719
{204CA507-752E-43A6-A094-794E40ABAE1F}.Release|Any CPU.Build.0 = Release|Any CPU
20+
{76D17C56-5643-4148-A504-8D6E24D24CAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21+
{76D17C56-5643-4148-A504-8D6E24D24CAD}.Debug|Any CPU.Build.0 = Debug|Any CPU
22+
{76D17C56-5643-4148-A504-8D6E24D24CAD}.Release|Any CPU.ActiveCfg = Release|Any CPU
23+
{76D17C56-5643-4148-A504-8D6E24D24CAD}.Release|Any CPU.Build.0 = Release|Any CPU
1824
EndGlobalSection
1925
GlobalSection(SolutionProperties) = preSolution
2026
HideSolutionNode = FALSE

src/Encryption/AesEncryption/BaseAesEncryption.cs

Lines changed: 27 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
using SafeCrypt.src.Encryption.AesEncryption.Models;
22
using System;
33
using System.IO;
4+
using System.Reflection;
45
using System.Security.Cryptography;
6+
using System.Text;
57

6-
namespace SafeCrypt.src.Encrypt.AesEncryption
8+
namespace SafeCrypt.AesEncryption
79
{
810
public class BaseAesEncryption
911
{
@@ -71,59 +73,42 @@ public virtual byte[] EncryptAES(ByteEncryptionParameters param)
7173
/// <exception cref="ArgumentNullException">
7274
/// Thrown if the input encrypted data, key, or initialization vector is null.
7375
/// </exception>
74-
public static byte[] DecryptAES(byte[] encryptedData, byte[] key, byte[] iv)
76+
public static byte[] DecryptAES(ByteDecryptionParameters param)
7577
{
76-
// Create an instance of the AES algorithm
77-
using (Aes aes = Aes.Create())
78+
try
7879
{
79-
// Set the key and initialization vector
80-
aes.Key = key;
81-
aes.IV = iv;
80+
// Create an instance of the AES algorithm
81+
using (Aes aes = Aes.Create())
82+
{
83+
// Set the key and initialization vector
84+
aes.Key = param.SecretKey;
85+
aes.IV = param.IV;
8286

83-
// Create a decryptor using the key and initialization vector
84-
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
87+
// Create a decryptor using the key and initialization vector
88+
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
8589

86-
// Use a MemoryStream to read the encrypted data
87-
using (MemoryStream memoryStream = new MemoryStream(encryptedData))
88-
{
89-
// Use a CryptoStream to perform the decryption
90-
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
90+
// Use a MemoryStream to read the encrypted data
91+
using (MemoryStream memoryStream = new MemoryStream(param.Data))
9192
{
92-
// Use a MemoryStream to store the decrypted data
93-
using (MemoryStream decryptedStream = new MemoryStream())
93+
// Use a CryptoStream to perform the decryption
94+
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
9495
{
95-
// Copy the decrypted data from the CryptoStream to the MemoryStream
96-
cryptoStream.CopyTo(decryptedStream);
97-
return decryptedStream.ToArray();
96+
// Use a MemoryStream to store the decrypted data
97+
using (MemoryStream decryptedStream = new MemoryStream())
98+
{
99+
// Copy the decrypted data from the CryptoStream to the MemoryStream
100+
cryptoStream.CopyTo(decryptedStream);
101+
return decryptedStream.ToArray();
102+
}
98103
}
99104
}
100105
}
101106
}
102-
}
103-
104-
105-
/// <summary>
106-
/// Generates an array of random bytes using a cryptographically secure random number generator.
107-
/// </summary>
108-
/// <param name="length">The length of the byte array to generate.</param>
109-
/// <returns>An array of random bytes or the IV key</returns>
110-
/// <remarks>
111-
/// The method uses a cryptographically secure random number generator (RNGCryptoServiceProvider) to generate
112-
/// a byte array with the specified length, providing a high level of randomness suitable for cryptographic use.
113-
/// </remarks>
114-
/// <param name="length">The desired length of the generated byte array.</param>
115-
/// <returns>An array of random bytes with the specified length.</returns>
116-
/// <exception cref="ArgumentException">
117-
/// Thrown if the specified length is less than or equal to zero.
118-
/// </exception>
119-
public static byte[] GenerateRandomIVKeyAsBytes(int length)
120-
{
121-
byte[] randomBytes = new byte[length];
122-
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
107+
catch (Exception ex)
123108
{
124-
rng.GetBytes(randomBytes);
109+
110+
throw;
125111
}
126-
return randomBytes;
127112
}
128113
}
129114
}

src/Encryption/AesEncryption/Decrypting.cs

Lines changed: 97 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,103 @@
1-
using SafeCrypt.src.Encrypt.AesEncryption;
2-
using SafeCrypt.src.Helpers;
1+
using SafeCrypt.AesEncryption;
2+
using SafeCrypt.Helpers;
3+
using SafeCrypt.Models;
4+
using SafeCrypt.src.Encryption.AesEncryption.Models;
35
using System;
46

5-
namespace SafeCrypt.src.Encryption.AesEncryption
7+
namespace SafeCrypt.AESDecryption
68
{
7-
public class Decrypting : BaseAesEncryption
9+
public class AesDecryption : BaseAesEncryption
810
{
9-
public byte[] AesDecrypt(string data, string secretKey, string iv)
11+
public DecryptionData DeEncryptFromHexString(DecryptionParameters param)
1012
{
11-
NullChecks(data, secretKey, iv);
13+
var responseData = new DecryptionData();
1214

13-
var (aesKey, aesIv) = ConvertKeysToBytesAndGetKeys(secretKey, iv);
15+
Validators.ValidateNotNull(param);
1416

15-
var aesData = data.HexadecimalStringToByteArray();
16-
return DecryptAES(aesData, aesKey, aesIv);
17+
// validate is base64
18+
if (!Validators.IsBase64String(param.SecretKey))
19+
{
20+
AddError(responseData, $"SecretKey: {param.SecretKey} is not a base64 string");
21+
return responseData;
22+
}
23+
24+
if (!Validators.IsBase64String(param.IV))
25+
{
26+
AddError(responseData, $"IV: {param.IV} is not a base64 string");
27+
return responseData;
28+
}
29+
// Convert input string to bytes
30+
byte[] dataBytes = param.IV.ConvertKeysToBytes();
31+
32+
// Validate block size based on AES algorithm's requirements
33+
if (!Validators.IsValidBlockSize(dataBytes.Length))
34+
{
35+
AddError(responseData, $"IV: {param.IV} is not a valid block size for this algorithm");
36+
return responseData;
37+
}
38+
39+
// Delegate the encryption to the underlying AES encryption method
40+
var byteEncryptionParameters = new ByteDecryptionParameters
41+
{
42+
SecretKey = Convert.FromBase64String(param.SecretKey),
43+
IV = dataBytes,
44+
Data = param.DataToDecrypt.HexadecimalStringToByteArray()
45+
};
46+
47+
var response = DecryptAES(byteEncryptionParameters);
48+
49+
return new DecryptionData
50+
{
51+
DecryptedData = response.BytesToString(),
52+
Iv = param.IV,
53+
SecretKey = param.SecretKey
54+
};
1755
}
1856

19-
public byte[] Decrypt(byte[] data, byte[] secretKey, byte[] iv)
20-
=> DecryptAES(data, secretKey, iv);
57+
public DecryptionData DecryptFromBase64String(DecryptionParameters param)
58+
{
59+
var responseData = new DecryptionData();
60+
61+
Validators.ValidateNotNull(param);
62+
63+
64+
if (!Validators.IsBase64String(param.SecretKey))
65+
{
66+
AddError(responseData, $"SecretKey: {param.SecretKey} is not a base64 string");
67+
return responseData;
68+
}
69+
70+
if (!Validators.IsBase64String(param.IV))
71+
{
72+
AddError(responseData, $"IV: {param.IV} is not a base64 string");
73+
return responseData;
74+
}
75+
76+
try
77+
{
78+
var byteDecryptionParameters = new ByteDecryptionParameters
79+
{
80+
SecretKey = Convert.FromBase64String(param.SecretKey),
81+
IV = Convert.FromBase64String(param.IV),
82+
Data = Convert.FromBase64String(param.DataToDecrypt)
83+
};
84+
85+
var response = DecryptAES(byteDecryptionParameters);
86+
87+
return new DecryptionData
88+
{
89+
DecryptedData = response.BytesToString(),
90+
Iv = param.IV,
91+
SecretKey = param.SecretKey
92+
};
93+
}
94+
catch (Exception ex)
95+
{
96+
// Handle decryption failure or padding errors
97+
AddError(responseData, $"Decryption error: {ex.Message}");
98+
return responseData;
99+
}
100+
}
21101

22102

23103
private void NullChecks(string data, string secretKey, string iv)
@@ -37,5 +117,11 @@ private void NullChecks(string data, string secretKey, string iv)
37117

38118
return (secretKey.ConvertKeysToBytes(), iv.ConvertKeysToBytes());
39119
}
120+
121+
private void AddError(DecryptionData responseData, string error)
122+
{
123+
responseData.HasError = true;
124+
responseData.Errors.Add(error);
125+
}
40126
}
41127
}

0 commit comments

Comments
 (0)