From 5b2d62318cc848def5b1d26059da1d08603b4958 Mon Sep 17 00:00:00 2001 From: Alex Bezdieniezhnykh Date: Fri, 28 Feb 2025 00:43:14 +0200 Subject: [PATCH] use CBC for encryption - interoperable with Cython --- Azaion.Services/Security.cs | 19 ++++++++++--------- Azaion.Test/SecurityTest.cs | 16 ++++++++++++++-- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/Azaion.Services/Security.cs b/Azaion.Services/Security.cs index d84233e..294682d 100644 --- a/Azaion.Services/Security.cs +++ b/Azaion.Services/Security.cs @@ -17,43 +17,44 @@ public static class Security public static string GetApiEncryptionKey(string email, string password, string? hardwareHash) => $"{email}-{password}-{hardwareHash}-#%@AzaionKey@%#---".ToHash(); - public static async Task EncryptTo(this Stream stream, Stream toStream, string key, CancellationToken cancellationToken = default) + public static async Task EncryptTo(this Stream inputStream, Stream toStream, string key, CancellationToken cancellationToken = default) { - if (stream is { CanRead: false }) throw new ArgumentNullException(nameof(stream)); + inputStream.Seek(0, SeekOrigin.Begin); + if (inputStream is { CanRead: false }) throw new ArgumentNullException(nameof(inputStream)); if (key is not { Length: > 0 }) throw new ArgumentNullException(nameof(key)); using var aes = Aes.Create(); - aes.Mode = CipherMode.CFB; + aes.Mode = CipherMode.CBC; + aes.Padding = PaddingMode.PKCS7; aes.Key = SHA256.HashData(Encoding.UTF8.GetBytes(key)); aes.GenerateIV(); using var encryptor = aes.CreateEncryptor(aes.Key, aes.IV); await using var cs = new CryptoStream(toStream, encryptor, CryptoStreamMode.Write, leaveOpen: true); - // Prepend IV to the encrypted data await toStream.WriteAsync(aes.IV.AsMemory(0, aes.IV.Length), cancellationToken); var buffer = new byte[BUFFER_SIZE]; int bytesRead; - while ((bytesRead = await stream.ReadAsync(buffer, cancellationToken)) > 0) + while ((bytesRead = await inputStream.ReadAsync(buffer, cancellationToken)) > 0) await cs.WriteAsync(buffer.AsMemory(0, bytesRead), cancellationToken); } - public static async Task DecryptTo(this Stream encryptedStream, Stream toStream, string key, CancellationToken cancellationToken = default) + public static async Task DecryptTo(this Stream encryptedStream, Stream toStream, string key, CancellationToken cancellationToken = default) { + encryptedStream.Seek(0, SeekOrigin.Begin); using var aes = Aes.Create(); aes.Key = SHA256.HashData(Encoding.UTF8.GetBytes(key)); - // Read the IV from the start of the input stream var iv = new byte[aes.BlockSize / 8]; _ = await encryptedStream.ReadAsync(iv, cancellationToken); aes.IV = iv; - aes.Mode = CipherMode.CFB; + aes.Mode = CipherMode.CBC; + aes.Padding = PaddingMode.PKCS7; using var decryptor = aes.CreateDecryptor(aes.Key, aes.IV); await using var cryptoStream = new CryptoStream(encryptedStream, decryptor, CryptoStreamMode.Read, leaveOpen: true); - // Read and write in chunks var buffer = new byte[BUFFER_SIZE]; int bytesRead; while ((bytesRead = await cryptoStream.ReadAsync(buffer, cancellationToken)) > 0) diff --git a/Azaion.Test/SecurityTest.cs b/Azaion.Test/SecurityTest.cs index a61424b..024a83e 100644 --- a/Azaion.Test/SecurityTest.cs +++ b/Azaion.Test/SecurityTest.cs @@ -13,7 +13,20 @@ public class SecurityTest [Fact] public async Task EncryptDecryptTest() { - var testString = "Hello World Test dfvjkhsdbfvkljh sabdljsdafv asdv"; + var testString = "Hello World Test dfvjkhsdbfvkljh sabdljsdafv asdvsad vsadfjv hbsadfkujv hgasdkvhgaksdjhvbsdv sdvsdjfhvb skdajfhb vskldfvhb lsdkfbv lsdb v" + + "sdlkfjv sdlkfvjb lsdkfjvb olsdfjvb l sdkfjvb lsdkf vblsdkfjbv lsdkfbvlksdjfbvlkdsjbfvlksdbv lksdjfbv lksdjbf vdsv sdf" + + "sdlkfjv sdlkfvjb lsdkfjvb olsdfjvb l sdkfjvb lsdkf vblsdkfjbv lsdkfbvlksdjfbvlkdsjbfvlksdbv lksdjfbv lksdjbf vdsv sdf" + + "sdlkfjv sdlkfvjb lsdkfjvb olsdfjvb l sdkfjvb lsdkf vblsdkfjbv lsdkfbvlksdjfbvlkdsjbfvlksdbv lksdjfbv lksdjbf vdsv sdf" + + "sdlkfjv sdlkfvjb lsdkfjvb olsdfjvb l sdkfjvb lsdkf vblsdkfjbv lsdkfbvlksdjfbvlkdsjbfvlksdbv lksdjfbv lksdjbf vdsv sdf" + + "sdlkfjv sdlkfvjb lsdkfjvb olsdfjvb l sdkfjvb lsdkf vblsdkfjbv lsdkfbvlksdjfbvlkdsjbfvlksdbv lksdjfbv lksdjbf vdsv sdf" + + "sdlkfjv sdlkfvjb lsdkfjvb olsdfjvb l sdkfjvb lsdkf vblsdkfjbv lsdkfbvlksdjfbvlkdsjbfvlksdbv lksdjfbv lksdjbf vdsv sdf" + + "sdlkfjv sdlkfvjb lsdkfjvb olsdfjvb l sdkfjvb lsdkf vblsdkfjbv lsdkfbvlksdjfbvlkdsjbfvlksdbv lksdjfbv lksdjbf vdsv sdf" + + "sdlkfjv sdlkfvjb lsdkfjvb olsdfjvb l sdkfjvb lsdkf vblsdkfjbv lsdkfbvlksdjfbvlkdsjbfvlksdbv lksdjfbv lksdjbf vdsv sdf" + + "sdlkfjv sdlkfvjb lsdkfjvb olsdfjvb l sdkfjvb lsdkf vblsdkfjbv lsdkfbvlksdjfbvlkdsjbfvlksdbv lksdjfbv lksdjbf vdsv sdf" + + "sdlkfjv sdlkfvjb lsdkfjvb olsdfjvb l sdkfjvb lsdkf vblsdkfjbv lsdkfbvlksdjfbvlkdsjbfvlksdbv lksdjfbv lksdjbf vdsv sdf" + + "sdlkfjv sdlkfvjb lsdkfjvb olsdfjvb l sdkfjvb lsdkf vblsdkfjbv lsdkfbvlksdjfbvlkdsjbfvlksdbv lksdjfbv lksdjbf vdsv sdf" + + + " sakdhvb kasjdhbv kjasdhv kjhas"; var email = "user@azaion.com"; var password = "testpw"; var hardwareId = "test_hardware_id"; @@ -22,7 +35,6 @@ public class SecurityTest 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);