using System.Security.Cryptography; using System.Text; using Azaion.Services; using FluentAssertions; using Newtonsoft.Json; using Xunit; namespace Azaion.Test; public class SecurityTest { [Fact] public async Task EncryptDecryptTest() { var testString = "Hello World Test dfvjkhsdbfvkljh sabdljsdafv asdv"; var email = "user@azaion.com"; var password = "testpw"; var hardwareId = "test_hardware_id"; var key = Security.MakeEncryptionKey(email, password, hardwareId); var encryptedStream = new MemoryStream(); await StringToStream(testString).EncryptTo(encryptedStream, key); encryptedStream.Seek(0, SeekOrigin.Begin); await using var decryptedStream = new MemoryStream(); await encryptedStream.DecryptTo(decryptedStream, key); encryptedStream.Close(); var str = StreamToString(decryptedStream); str.Should().Be(testString); } [Fact] public async Task EncryptDecryptLargeFileTest() { var username = "user@azaion.com"; var password = "testpw"; var hardwareId = "test_hardware_id"; var key = Security.MakeEncryptionKey(username, password, hardwareId); var largeFilePath = "large.txt"; var largeFileDecryptedPath = "large_decrypted.txt"; var stream = await CreateLargeFile(largeFilePath); stream.Seek(0, SeekOrigin.Begin); var encryptedStream = new MemoryStream(); await stream.EncryptTo(encryptedStream, key); encryptedStream.Seek(0, SeekOrigin.Begin); File.Delete(largeFileDecryptedPath); await using var decryptedStream = new FileStream(largeFileDecryptedPath, FileMode.OpenOrCreate, FileAccess.Write); await encryptedStream.DecryptTo(decryptedStream, key); encryptedStream.Close(); stream.Close(); decryptedStream.Close(); await CompareFiles(largeFilePath, largeFileDecryptedPath); File.Delete(largeFilePath); File.Delete(largeFileDecryptedPath); } private async Task CompareFiles(string largeFilePath, string largeFileDecryptedPath) { await using var stream1 = new FileStream(largeFilePath, FileMode.Open, FileAccess.Read); await using var stream2 = new FileStream(largeFileDecryptedPath, FileMode.Open, FileAccess.Read); var sha256Bytes1 = Encoding.UTF8.GetString(await SHA256.HashDataAsync(stream1)); var sha256Bytes2 = Encoding.UTF8.GetString(await SHA256.HashDataAsync(stream2)); sha256Bytes1.Should().Be(sha256Bytes2); } private async Task CreateLargeFile(string largeTxtPath) { var max = 4000000; File.Delete(largeTxtPath); var stream = new FileStream(largeTxtPath, FileMode.OpenOrCreate, FileAccess.ReadWrite); var numbersList = Enumerable.Range(1, max).Chunk(100000); foreach (var numbers in numbersList) { var dict = numbers.ToDictionary(x => x, _ => DateTime.UtcNow); var bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(dict, Formatting.Indented)); await stream.WriteAsync(bytes); Console.WriteLine($"Writing numbers from {(numbers.FirstOrDefault()*100 / (double)max):F1} %"); } await stream.FlushAsync(); return stream; } private static string StreamToString(Stream stream) { stream.Position = 0; using var reader = new StreamReader(stream, Encoding.UTF8); return reader.ReadToEnd(); } private static Stream StringToStream(string src) { var byteArray = Encoding.UTF8.GetBytes(src); return new MemoryStream(byteArray); } }