From 35cea6d5693118d9117f0a49f7c73cd936330c44 Mon Sep 17 00:00:00 2001 From: Haik Date: Fri, 19 Jan 2024 11:44:57 +0400 Subject: [PATCH] Gzip compression added --- Readme.md | 82 +++++++++++++----- src/Pandatech.Crypto.Tests/GZipTests.cs | 84 +++++++++++++++++++ .../Pandatech.Crypto.Tests.csproj | 4 +- src/Pandatech.Crypto/GZip.cs | 45 ++++++++++ src/Pandatech.Crypto/Pandatech.Crypto.csproj | 4 +- 5 files changed, 195 insertions(+), 24 deletions(-) create mode 100644 src/Pandatech.Crypto.Tests/GZipTests.cs create mode 100644 src/Pandatech.Crypto/GZip.cs diff --git a/Readme.md b/Readme.md index 37c7664..fd3704d 100644 --- a/Readme.md +++ b/Readme.md @@ -1,15 +1,37 @@ -# PandaTech.Crypto - -## Introduction +# 1. PandaTech.Crypto + + +- [1. PandaTech.Crypto](#1-pandatechcrypto) + - [1.1. Introduction](#11-introduction) + - [1.2. Features](#12-features) + - [1.3. Installation](#13-installation) + - [1.4. How to Use](#14-how-to-use) + - [1.4.1. Configuring Dependency Injection](#141-configuring-dependency-injection) + - [1.4.2. AES256 Class](#142-aes256-class) + - [1.4.2.1. Immutable Configurations](#1421-immutable-configurations) + - [1.4.2.2. Encryption/Decryption methods with hashing](#1422-encryptiondecryption-methods-with-hashing) + - [1.4.2.3. Encryption/Decryption methods without hashing](#1423-encryptiondecryption-methods-without-hashing) + - [1.4.2.4. Encryption/Decryption methods with custom key (overriding options for one time)](#1424-encryptiondecryption-methods-with-custom-key-overriding-options-for-one-time) + - [1.4.3. Argon2id Class](#143-argon2id-class) + - [1.4.3.1. Default Configurations](#1431-default-configurations) + - [1.4.3.2 Hash password and verify hash](#1432-hash-password-and-verify-hash) + - [1.4.4. Random Class](#144-random-class) + - [1.4.5. Password Class](#145-password-class) + - [1.4.6. Sha3 Class](#146-sha3-class) + - [1.4.7. GZip Class](#147-gzip-class) + - [1.5. License](#15-license) + +## 1.1. Introduction Pandatech.Crypto is a powerful cryptographic utility library backed by 99% test coverage through unit tests. The library offers an array of static methods for secure data operations, including AES256 encryption and decryption, Argon2Id -password hashing and verification, as well as utilities for generating cryptographic random bytes and passwords. +password hashing and verification, as well as utilities for generating cryptographic random bytes and passwords. Now, it +also includes GZip compression and decompression functionalities. Designed to work efficiently in containerized environments, the library performs effectively even with limited resources—hash generation takes under 500ms on a container with 1 vCore and 1GB of RAM. -## Features +## 1.2. Features * **AES 256-bit Encryption/Decryption:** Encrypt your data and get the IV and encrypted bytes in one array. Decrypt it back to its original form, seamlessly handling the IV. Note that you have option to encrypt with hash and decrypt @@ -20,19 +42,21 @@ resources—hash generation takes under 500ms on a container with 1 vCore and 1G * **SHA-3 Hashing:** Utilize 512-bit SHA-3 hashing for various applications. * **Random Number/Password Generation:** Generate cryptographic random bytes, AES256 keys, or strong passwords with specific character sets. +* **GZip Compression/Decompression:** Efficiently compress and decompress data using GZip, with support for byte arrays + and streams. * **Performance Optimized:** Tested to run efficiently in resource-constrained environments. * **High Test Coverage:** Confidence backed by 99% unit test coverage. -## Installation +## 1.3. Installation To use `PandaTech.Crypto` in your project, install the NuGet package using the following command in the Package Manager Console: `Install-Package PandaTech.Crypto` or, search for "PandaTech.Crypto" in the NuGet Package Manager and install it from there. -## How to Use +## 1.4. How to Use -### 1. Configuring Dependency Injection +### 1.4.1. Configuring Dependency Injection First, you'll need to configure Aes256 and Argon2Id in your application. To do so, add the following code to your `Program.cs` file: @@ -56,28 +80,28 @@ builder.services.AddPandatechCryptoAes256(options => }); ``` -### 2. AES256 Class +### 1.4.2. AES256 Class -#### Immutable Configurations +#### 1.4.2.1. Immutable Configurations 1. **IV**: A random IV is generated for each Encryption, enhancing security. 2. **PaddingMode**: PKCS7 -#### Encryption/Decryption methods with hashing +#### 1.4.2.2. Encryption/Decryption methods with hashing ```csharp byte[] cipherText = aes256.Encrypt("your-plaintext"); string plainText = aes256.Decrypt(cipherText); ``` -#### Encryption/Decryption methods without hashing +#### 1.4.2.3. Encryption/Decryption methods without hashing ```csharp byte[] cipherText = aes256.Encrypt("your-plaintext", false); string plainText = aes256.Decrypt(cipherText, false); ``` -#### Encryption/Decryption methods with custom key (overriding options for one time) +#### 1.4.2.4. Encryption/Decryption methods with custom key (overriding options for one time) ```csharp string customKey = "your-custom-base64-encoded-key"; @@ -85,16 +109,16 @@ byte[] cipherText = aes256.Encrypt("your-plaintext", customKey); string plainText = aes256.Decrypt(cipherText, customKey); ``` -### 2. Argon2id Class +### 1.4.3. Argon2id Class -#### Default Configurations +#### 1.4.3.1. Default Configurations 1. **Salt**: A random salt is generated for each password hash, enhancing security. 2. **DegreeOfParallelism**: 8 3. **Iterations**: 5 4. **MemorySize**: 128 MB -Hash password and verify hash +#### 1.4.3.2 Hash password and verify hash ```csharp // Example usage for hashing @@ -104,14 +128,14 @@ var hashedPassword = _argon2Id.HashPassword("yourPassword"); var isPasswordValid = _argon2Id.VerifyHash("yourPassword", hashedPassword); ``` -### 3. Random Class +### 1.4.4. Random Class ```csharp var randomBytes = Random.GenerateBytes(16); var aesKey = Random.GenerateAes256KeyString(); ``` -### 4. Password Class +### 1.4.5. Password Class ```csharp var includeUppercase = true; @@ -126,7 +150,7 @@ string password = Password.GenerateRandom(16, includeUppercase, includeLowercase bool isValid = Password.Validate(password, 16, includeUppercase, includeLowercase, includeDigits, includeSpecialChars); ``` -### 5. Sha3 Class +### 1.4.6. Sha3 Class ```csharp // Example usage for generating hash @@ -136,6 +160,24 @@ var sha3Hash = Sha3.Hash("yourPlainText"); var isHashValid = Sha3.VerifyHash("yourPlainText", sha3Hash); ``` -## License +### 1.4.7. GZip Class + +Compression and Decompression +The `GZip` class provides methods for compressing and decompressing data using GZip. It supports operations on strings, byte arrays, and streams. + +Example usage for compressing and decompressing a string: +```csharp +using Pandatech.Crypto; + +// Compress a string +string data = "Sample Data"; +byte[] compressedData = GZip.Compress(data); + +// Decompress back to string +string decompressedData = Encoding.UTF8.GetString(GZip.Decompress(compressedData)); + +``` + +## 1.5. License PandaTech.Crypto is licensed under the MIT License. \ No newline at end of file diff --git a/src/Pandatech.Crypto.Tests/GZipTests.cs b/src/Pandatech.Crypto.Tests/GZipTests.cs new file mode 100644 index 0000000..1491175 --- /dev/null +++ b/src/Pandatech.Crypto.Tests/GZipTests.cs @@ -0,0 +1,84 @@ +using System.Text; + +namespace Pandatech.Crypto.Tests; + +public class GZipTests +{ + [Fact] + public void Compress_String_ReturnsCompressedData() + { + // Arrange + const string input = "Hello, world!"; + var expected = GZip.Compress(Encoding.UTF8.GetBytes(input)); + + // Act + var result = GZip.Compress(input); + + // Assert + Assert.Equal(expected, result); + } + + [Fact] + public void Decompress_Base64_ReturnsOriginalData() + { + // Arrange + const string input = "Hello, world!"; + var compressed = GZip.Compress(input); + var compressedBase64 = Convert.ToBase64String(compressed); + + // Act + var result = GZip.Decompress(compressedBase64); + var resultString = Encoding.UTF8.GetString(result); + + // Assert + Assert.Equal(input, resultString); + } + + [Fact] + public void Compress_And_Decompress_Byte_Array_ReturnsOriginalData() + { + // Arrange + var input = Encoding.UTF8.GetBytes("Hello, world!"); + + // Act + var compressed = GZip.Compress(input); + var decompressed = GZip.Decompress(compressed); + + // Assert + Assert.Equal(input, decompressed); + } + + [Fact] + public void Compress_And_Decompress_Stream_ReturnsOriginalData() + { + // Arrange + var input = "Hello, world!"u8.ToArray(); + using var inputStream = new MemoryStream(input); + using var compressedStream = new MemoryStream(); + using var decompressedStream = new MemoryStream(); + + // Act + GZip.Compress(inputStream, compressedStream); + compressedStream.Seek(0, SeekOrigin.Begin); + GZip.Decompress(compressedStream, decompressedStream); + var result = decompressedStream.ToArray(); + + // Assert + Assert.Equal(input, result); + } + + [Theory] + [InlineData("")] + [InlineData("Short string")] + [InlineData("The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.")] + public void Compress_Decompress_String_VariousLengths(string input) + { + // Act + var compressed = GZip.Compress(input); + var decompressed = GZip.Decompress(Convert.ToBase64String(compressed)); + var resultString = Encoding.UTF8.GetString(decompressed); + + // Assert + Assert.Equal(input, resultString); + } +} \ No newline at end of file diff --git a/src/Pandatech.Crypto.Tests/Pandatech.Crypto.Tests.csproj b/src/Pandatech.Crypto.Tests/Pandatech.Crypto.Tests.csproj index 4231b75..840a371 100644 --- a/src/Pandatech.Crypto.Tests/Pandatech.Crypto.Tests.csproj +++ b/src/Pandatech.Crypto.Tests/Pandatech.Crypto.Tests.csproj @@ -11,8 +11,8 @@ - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/src/Pandatech.Crypto/GZip.cs b/src/Pandatech.Crypto/GZip.cs new file mode 100644 index 0000000..7b0c01f --- /dev/null +++ b/src/Pandatech.Crypto/GZip.cs @@ -0,0 +1,45 @@ +using System.IO.Compression; +using System.Text; + +namespace Pandatech.Crypto; + +public static class GZip +{ + + public static byte[] Compress(string data) + { + return Compress(Encoding.UTF8.GetBytes(data)); + } + + public static byte[] Compress(byte[] data) + { + using var compressedStream = new MemoryStream(); + Compress(new MemoryStream(data), compressedStream); + return compressedStream.ToArray(); + } + + public static void Compress(Stream sourceStream, Stream destinationStream) + { + using var zipStream = new GZipStream(destinationStream, CompressionMode.Compress, leaveOpen: true); + sourceStream.CopyTo(zipStream); + } + + public static byte[] Decompress(string compressedBase64) + { + var compressedData = Convert.FromBase64String(compressedBase64); + return Decompress(compressedData); + } + + public static byte[] Decompress(byte[] data) + { + using var decompressedStream = new MemoryStream(); + Decompress(new MemoryStream(data), decompressedStream); + return decompressedStream.ToArray(); + } + + public static void Decompress(Stream sourceStream, Stream destinationStream) + { + using var zipStream = new GZipStream(sourceStream, CompressionMode.Decompress, leaveOpen: true); + zipStream.CopyTo(destinationStream); + } +} \ No newline at end of file diff --git a/src/Pandatech.Crypto/Pandatech.Crypto.csproj b/src/Pandatech.Crypto/Pandatech.Crypto.csproj index b32deba..f53dd78 100644 --- a/src/Pandatech.Crypto/Pandatech.Crypto.csproj +++ b/src/Pandatech.Crypto/Pandatech.Crypto.csproj @@ -8,12 +8,12 @@ MIT pandatech.png Readme.md - 2.2.3 + 2.2.4 Pandatech.Crypto Pandatech, library, encryption, hash, algorythms, security PandaTech.Crypto is a .NET library simplifying common cryptograhic functions. https://github.com/PandaTechAM/be-lib-pandatech-crypto - Structure change + Added GZip compression