Add cryptography project

This commit is contained in:
Leendert de Borst
2024-06-01 22:29:25 +02:00
parent 7190cb0544
commit a6eb89e863
5 changed files with 169 additions and 0 deletions
+7
View File
@@ -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>
+63
View File
@@ -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>