diff --git a/Readme.md b/Readme.md index fd3704d..a776632 100644 --- a/Readme.md +++ b/Readme.md @@ -1,25 +1,26 @@ # 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](#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.4.8. Mask Class](#148-mask-class) + - [1.4.8.1. Masking Email Addresses](#1481-masking-email-addresses) + - [1.5. License](#15-license) ## 1.1. Introduction @@ -44,6 +45,8 @@ resources—hash generation takes under 500ms on a container with 1 vCore and 1G specific character sets. * **GZip Compression/Decompression:** Efficiently compress and decompress data using GZip, with support for byte arrays and streams. +* **Masking:** Mask sensitive information like email addresses and phone numbers, ensuring that they are partially + hidden and thus safeguarded. * **Performance Optimized:** Tested to run efficiently in resource-constrained environments. * **High Test Coverage:** Confidence backed by 99% unit test coverage. @@ -163,9 +166,11 @@ var isHashValid = Sha3.VerifyHash("yourPlainText", sha3Hash); ### 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. +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; @@ -175,7 +180,27 @@ byte[] compressedData = GZip.Compress(data); // Decompress back to string string decompressedData = Encoding.UTF8.GetString(GZip.Decompress(compressedData)); +``` + +### 1.4.8. Mask Class + +The `Mask` class in the PandaTech.Crypto library provides methods to mask sensitive information like email addresses and +phone numbers, ensuring that they are partially hidden and thus safeguarded. + +#### 1.4.8.1. Masking Email Addresses + +The `MaskEmail` method masks the local part of an email address, showing only the first two characters and replacing the +rest with asterisks (*), keeping the domain part intact. + +```csharp +// Example usage for masking an email +string maskedEmail = Mask.MaskEmail("example@email.com"); + +// Output: "ex*****@email.com" +// Example usage for masking a phone number +string maskedPhone = Mask.MaskPhoneNumber("1234567890"); +// Output: "******7890" ``` ## 1.5. License diff --git a/src/Pandatech.Crypto.Tests/MaskTests.cs b/src/Pandatech.Crypto.Tests/MaskTests.cs new file mode 100644 index 0000000..75a9d08 --- /dev/null +++ b/src/Pandatech.Crypto.Tests/MaskTests.cs @@ -0,0 +1,45 @@ +namespace Pandatech.Crypto.Tests; + +using Xunit; +using Crypto; +using System; + +public class MaskTests +{ + [Theory] + [InlineData("vazgen.Sargsyan@vazgen.com", "va***************@vazgen.com")] + [InlineData("test@example.com", "te**@example.com")] + [InlineData("ab@c.com", "ab@c.com")] + [InlineData("a@b.com", "a@b.com")] + public void MaskEmail_ValidEmails_ReturnsMaskedEmail(string input, string expected) + { + var result = Mask.MaskEmail(input); + Assert.Equal(expected, result); + } + + [Theory] + [InlineData("")] + [InlineData("notanemail")] + public void MaskEmail_InvalidEmails_ThrowsArgumentException(string input) + { + Assert.Throws(() => Mask.MaskEmail(input)); + } + + [Theory] + [InlineData("1234567890", "******7890")] + [InlineData("1234", "1234")] + [InlineData("12", "12")] + public void MaskPhoneNumber_ValidPhoneNumbers_ReturnsMaskedPhone(string input, string expected) + { + var result = Mask.MaskPhoneNumber(input); + Assert.Equal(expected, result); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + public void MaskPhoneNumber_InvalidPhoneNumbers_ThrowsArgumentException(string input) + { + Assert.Throws(() => Mask.MaskPhoneNumber(input)); + } +} \ No newline at end of file diff --git a/src/Pandatech.Crypto/Mask.cs b/src/Pandatech.Crypto/Mask.cs new file mode 100644 index 0000000..f43a9d3 --- /dev/null +++ b/src/Pandatech.Crypto/Mask.cs @@ -0,0 +1,34 @@ +using RegexBox; + +namespace Pandatech.Crypto; + +public static class Mask +{ + public static string MaskEmail(string email) + { + if (!PandaValidator.IsEmail(email)) + { + throw new ArgumentException("Invalid email address", nameof(email)); + } + + var parts = email.Split('@'); + var localPart = parts[0]; + var domainPart = parts[1]; + + var maskedLocalPart = + localPart.Length <= 2 ? localPart : localPart[..2] + new string('*', localPart.Length - 2); + return $"{maskedLocalPart}@{domainPart}"; + } + + public static string MaskPhoneNumber(string phoneNumber) + { + if (string.IsNullOrEmpty(phoneNumber)) + { + throw new ArgumentException("Invalid phone number", nameof(phoneNumber)); + } + + return phoneNumber.Length <= 4 + ? phoneNumber + : string.Concat(new string('*', phoneNumber.Length - 4), phoneNumber.AsSpan(phoneNumber.Length - 4)); + } +} \ No newline at end of file diff --git a/src/Pandatech.Crypto/Pandatech.Crypto.csproj b/src/Pandatech.Crypto/Pandatech.Crypto.csproj index f53dd78..a107e89 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.4 + 2.2.5 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 - Added GZip compression + Added Mask class @@ -25,6 +25,7 @@ +