Add cryptography project
This commit is contained in:
@@ -12,6 +12,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FaviconExtractor", "src\Uti
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AliasVault.Tests", "src\AliasVault.Tests\AliasVault.Tests.csproj", "{8E6A418A-B305-465D-857D-49953605C18E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cryptography", "src\Utilities\Cryptography\Cryptography.csproj", "{427EA8E2-EA76-467E-A6BC-201EFE40C0D0}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -38,8 +40,13 @@ Global
|
||||
{8E6A418A-B305-465D-857D-49953605C18E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8E6A418A-B305-465D-857D-49953605C18E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8E6A418A-B305-465D-857D-49953605C18E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{427EA8E2-EA76-467E-A6BC-201EFE40C0D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{427EA8E2-EA76-467E-A6BC-201EFE40C0D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{427EA8E2-EA76-467E-A6BC-201EFE40C0D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{427EA8E2-EA76-467E-A6BC-201EFE40C0D0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{ED328644-A152-403D-86EB-81201AA07744} = {01AB9389-2F89-4F8E-A688-BF4BF1FC42C8}
|
||||
{427EA8E2-EA76-467E-A6BC-201EFE40C0D0} = {01AB9389-2F89-4F8E-A688-BF4BF1FC42C8}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Utilities\Cryptography\Cryptography.csproj" />
|
||||
<ProjectReference Include="..\Utilities\FaviconExtractor\FaviconExtractor.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace AliasVault.Tests;
|
||||
|
||||
public class CryptographyTests
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test basic encryption and decryption using default encryption logic (Argon2id and AES-256).
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestBasicEncrypt()
|
||||
{
|
||||
string password = "your-password";
|
||||
string salt = "your-salt"; // Use a secure random salt in production
|
||||
|
||||
string plaintext = "Hello, World!";
|
||||
|
||||
// Derive a key from the password using Argon2id
|
||||
byte[] key = Cryptography.Cryptography.DeriveKeyFromPassword(password, salt);
|
||||
Console.Write($"Derived key: {key})");
|
||||
|
||||
// Encrypt the plaintext
|
||||
string encrypted = Cryptography.Cryptography.Encrypt(plaintext, key);
|
||||
Console.WriteLine($"Encrypted: {encrypted}");
|
||||
|
||||
Assert.That(encrypted, Is.Not.Null);
|
||||
Assert.That(encrypted, Is.Not.Empty);
|
||||
Assert.That(encrypted, Is.Not.EqualTo(plaintext));
|
||||
|
||||
|
||||
// Decrypt the ciphertext
|
||||
string decrypted = Cryptography.Cryptography.Decrypt(encrypted, key);
|
||||
Console.WriteLine($"Decrypted: {decrypted}");
|
||||
Assert.That(decrypted, Is.EqualTo(plaintext));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test basic encryption and decryption using default encryption logic (Argon2id and AES-256).
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestNotEqualsPassword()
|
||||
{
|
||||
string password = "your-password";
|
||||
string salt = "your-salt"; // Use a secure random salt in production
|
||||
|
||||
string plaintext = "Hello, World!";
|
||||
|
||||
// Derive a key from the password using Argon2id
|
||||
byte[] key = Cryptography.Cryptography.DeriveKeyFromPassword(password, salt);
|
||||
// Encrypt the plaintext
|
||||
string encrypted = Cryptography.Cryptography.Encrypt(plaintext, key);
|
||||
|
||||
// Decrypt the ciphertext using a different key
|
||||
byte[] key2 = Cryptography.Cryptography.DeriveKeyFromPassword("your-password2", salt);
|
||||
|
||||
Assert.Throws<CryptographicException>(() => Cryptography.Cryptography.Decrypt(encrypted, key2));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Konscious.Security.Cryptography;
|
||||
|
||||
namespace Cryptography;
|
||||
|
||||
public class Cryptography
|
||||
{
|
||||
public static byte[] DeriveKeyFromPassword(string password, string salt)
|
||||
{
|
||||
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
|
||||
byte[] saltBytes = Encoding.UTF8.GetBytes(salt);
|
||||
|
||||
var argon2 = new Argon2id(passwordBytes)
|
||||
{
|
||||
Salt = saltBytes,
|
||||
DegreeOfParallelism = 8,
|
||||
MemorySize = 65536,
|
||||
Iterations = 4
|
||||
};
|
||||
|
||||
return argon2.GetBytes(32); // Generate a 256-bit key
|
||||
}
|
||||
|
||||
public static string Encrypt(string plaintext, byte[] key)
|
||||
{
|
||||
using (Aes aes = Aes.Create())
|
||||
{
|
||||
aes.Key = key;
|
||||
aes.GenerateIV();
|
||||
|
||||
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
|
||||
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
|
||||
{
|
||||
using (StreamWriter sw = new StreamWriter(cs))
|
||||
{
|
||||
sw.Write(plaintext);
|
||||
}
|
||||
}
|
||||
|
||||
byte[] iv = aes.IV;
|
||||
byte[] encryptedContent = ms.ToArray();
|
||||
|
||||
byte[] result = new byte[iv.Length + encryptedContent.Length];
|
||||
Buffer.BlockCopy(iv, 0, result, 0, iv.Length);
|
||||
Buffer.BlockCopy(encryptedContent, 0, result, iv.Length, encryptedContent.Length);
|
||||
|
||||
return Convert.ToBase64String(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string Decrypt(string ciphertext, byte[] key)
|
||||
{
|
||||
byte[] fullCipher = Convert.FromBase64String(ciphertext);
|
||||
|
||||
byte[] iv = new byte[16];
|
||||
byte[] cipher = new byte[fullCipher.Length - iv.Length];
|
||||
|
||||
Buffer.BlockCopy(fullCipher, 0, iv, 0, iv.Length);
|
||||
Buffer.BlockCopy(fullCipher, iv.Length, cipher, 0, cipher.Length);
|
||||
|
||||
using (Aes aes = Aes.Create())
|
||||
{
|
||||
aes.Key = key;
|
||||
aes.IV = iv;
|
||||
|
||||
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
|
||||
|
||||
using (MemoryStream ms = new MemoryStream(cipher))
|
||||
{
|
||||
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
|
||||
{
|
||||
using (StreamReader sr = new StreamReader(cs))
|
||||
{
|
||||
return sr.ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Konscious.Security.Cryptography.Argon2" Version="1.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user