diff --git a/MD5CSharp.Test/MD5.Test/SaltTeste/SaltTest.cs b/MD5CSharp.Test/MD5.Test/SaltTeste/SaltTest.cs new file mode 100644 index 0000000..91019ea --- /dev/null +++ b/MD5CSharp.Test/MD5.Test/SaltTeste/SaltTest.cs @@ -0,0 +1,154 @@ +using MD5Hash; +using System.IO; +using System.Text; +using Xunit; + +namespace MD5.Test +{ + public class SaltTest + { + [Fact] + public void MD5HashGetMD5WithSalt_ShouldReturnDifferentHashesForSameInputWithDifferentSalts() + { + string input = "hello world"; + string salt1 = "randomSalt1"; + string salt2 = "randomSalt2"; + + string hash1 = input.GetMD5WithSalt(salt1); + string hash2 = input.GetMD5WithSalt(salt2); + + Assert.NotNull(hash1); + Assert.NotNull(hash2); + Assert.NotEqual(hash1, hash2); + } + + [Fact] + public void MD5HashGetMD5WithSalt_ShouldReturnSameHashForSameInputAndSameSalt() + { + string input = "hello world"; + string salt = "randomSalt"; + + string hash1 = input.GetMD5WithSalt(salt); + string hash2 = input.GetMD5WithSalt(salt); + + Assert.NotNull(hash1); + Assert.NotNull(hash2); + Assert.Equal(hash1, hash2); + } + + [Fact] + public void MD5HashGetMD5WithSalt_ShouldReturnNullForNullInput() + { + string input = null; + string salt = "randomSalt"; + + string hash = input.GetMD5WithSalt(salt); + + Assert.Null(hash); + } + + [Fact] + public void MD5HashGetMD5WithSalt_ShouldReturnDifferentHashesForDifferentInputsWithSameSalt() + { + string input1 = "hello world"; + string input2 = "goodbye world"; + string salt = "randomSalt"; + + string hash1 = input1.GetMD5WithSalt(salt); + string hash2 = input2.GetMD5WithSalt(salt); + + Assert.NotNull(hash1); + Assert.NotNull(hash2); + Assert.NotEqual(hash1, hash2); + } + + [Fact] + public void MD5HashGetMD5WithSalt_Object_ShouldReturnDifferentHashesForDifferentObjectsWithSameSalt() + { + var obj1 = new { Id = 1, Name = "Test1" }; + var obj2 = new { Id = 2, Name = "Test2" }; + string salt = "randomSalt"; + + string hash1 = obj1.GetMD5WithSalt(salt); + string hash2 = obj2.GetMD5WithSalt(salt); + + Assert.NotNull(hash1); + Assert.NotNull(hash2); + Assert.NotEqual(hash1, hash2); + } + + [Fact] + public void MD5HashGetMD5WithSalt_Object_ShouldReturnSameHashForSameObjectAndSameSalt() + { + var obj = new { Id = 1, Name = "Test" }; + string salt = "randomSalt"; + + string hash1 = obj.GetMD5WithSalt(salt); + string hash2 = obj.GetMD5WithSalt(salt); + + Assert.NotNull(hash1); + Assert.NotNull(hash2); + Assert.Equal(hash1, hash2); + } + + [Fact] + public void MD5HashGetMD5WithSalt_ByteArray_ShouldReturnDifferentHashesForDifferentByteArraysWithSameSalt() + { + byte[] byteArray1 = Encoding.UTF8.GetBytes("Hello, World!"); + byte[] byteArray2 = Encoding.UTF8.GetBytes("Goodbye, World!"); + byte[] salt = Encoding.UTF8.GetBytes("randomSalt"); + + string hash1 = byteArray1.GetMD5WithSalt(salt); + string hash2 = byteArray2.GetMD5WithSalt(salt); + + Assert.NotNull(hash1); + Assert.NotNull(hash2); + Assert.NotEqual(hash1, hash2); + } + + [Fact] + public void MD5HashGetMD5WithSalt_ByteArray_ShouldReturnSameHashForSameByteArrayAndSameSalt() + { + byte[] byteArray = Encoding.UTF8.GetBytes("Hello, World!"); + byte[] salt = Encoding.UTF8.GetBytes("randomSalt"); + + string hash1 = byteArray.GetMD5WithSalt(salt); + string hash2 = byteArray.GetMD5WithSalt(salt); + + Assert.NotNull(hash1); + Assert.NotNull(hash2); + Assert.Equal(hash1, hash2); + } + + [Fact] + public void MD5HashGetMD5WithSalt_Stream_ShouldReturnDifferentHashesForDifferentStreamsWithSameSalt() + { + var stream1 = new MemoryStream(Encoding.UTF8.GetBytes("Hello, World!")); + var stream2 = new MemoryStream(Encoding.UTF8.GetBytes("Goodbye, World!")); + byte[] salt = Encoding.UTF8.GetBytes("randomSalt"); + + string hash1 = stream1.GetMD5WithSalt(salt); + string hash2 = stream2.GetMD5WithSalt(salt); + + Assert.NotNull(hash1); + Assert.NotNull(hash2); + Assert.NotEqual(hash1, hash2); + } + + [Fact] + public void MD5HashGetMD5WithSalt_Stream_ShouldReturnSameHashForSameStreamAndSameSalt() + { + var stream = new MemoryStream(Encoding.UTF8.GetBytes("Hello, World!")); + byte[] salt = Encoding.UTF8.GetBytes("randomSalt"); + + string hash1 = stream.GetMD5WithSalt(salt); + stream.Position = 0; + string hash2 = stream.GetMD5WithSalt(salt); + + Assert.NotNull(hash1); + Assert.NotNull(hash2); + Assert.Equal(hash1, hash2); + } + + } +} \ No newline at end of file diff --git a/MD5CSharp/Hash.cs b/MD5CSharp/Hash.cs index 4065baa..26a310f 100644 --- a/MD5CSharp/Hash.cs +++ b/MD5CSharp/Hash.cs @@ -10,8 +10,6 @@ public static class Hash { public static string Content(string text, EncodingType encodingType = EncodingType.ASCII) => GetHash(text, encodingType); - public static string GetMD5(this string text, EncodingType encodingType = EncodingType.ASCII) => GetHash(text, encodingType); - public static string GetMD5(this object value, EncodingType encodingType = EncodingType.UTF8) { try @@ -30,6 +28,68 @@ public static string GetMD5(this object value, EncodingType encodingType = Encod public static string GetMD5(this Stream stream) => HashBuilder(stream); + public static string GetMD5(this string text, EncodingType encodingType = EncodingType.ASCII) => GetHash(text, encodingType); + + public static string GetMD5WithSalt(this string text, string salt, EncodingType encodingType = EncodingType.UTF8) + { + if (string.IsNullOrEmpty(text)) + return null; + + string saltedText = $"{salt}{text}"; + return GetHash(saltedText, encodingType); + } + + public static string GetMD5WithSalt(this object value, string salt, EncodingType encodingType = EncodingType.UTF8) + { + try + { + string text = JsonConvert.SerializeObject(value); + string saltedText = $"{salt}{text}"; + return GetHash(saltedText, encodingType); + } + catch (Exception ex) + { + Console.WriteLine($"Error in GetMD5WithSalt: {ex.Message}"); + return null; + } + } + + public static string GetMD5WithSalt(this byte[] byteArray, byte[] salt) + { + if (byteArray == null || salt == null) + return null; + + byte[] saltedBytes = Combine(byteArray, salt); + return HashBuilder(saltedBytes); + } + + public static string GetMD5WithSalt(this Stream stream, byte[] salt) + { + try + { + using (MemoryStream memoryStream = new MemoryStream()) + { + stream.CopyTo(memoryStream); + byte[] streamBytes = memoryStream.ToArray(); + byte[] saltedBytes = Combine(streamBytes, salt); + return HashBuilder(saltedBytes); + } + } + catch (Exception ex) + { + Console.WriteLine($"Error in GetMD5WithSalt: {ex.Message}"); + return null; + } + } + + private static byte[] Combine(byte[] first, byte[] second) + { + byte[] result = new byte[first.Length + second.Length]; + Buffer.BlockCopy(first, 0, result, 0, first.Length); + Buffer.BlockCopy(second, 0, result, first.Length, second.Length); + return result; + } + private static string GetHash(this string text, EncodingType encodingType = EncodingType.ASCII) { byte[] bytes = GetBytesWithEncoding(text, encodingType); diff --git a/README.md b/README.md index fa5f8de..1554a99 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -![Nuget](https://img.shields.io/nuget/dt/md5) + +![Nuget](https://img.shields.io/nuget/dt/md5) ![Nuget](https://img.shields.io/nuget/v/md5) # MD5 @@ -36,6 +37,37 @@ To number you can use: string hash = myNumber.ToString().GetMD5(): ``` +## New Feature: MD5 with Salt + +This new feature allows you to generate a salted MD5 hash, enhancing security. + +### Usage + +To use the salted hash functionality, you can call the `GetMD5WithSalt` method on a string, byteArray, or object to get the MD5 hash with a salt. +Examples: + +```csharp +string salt = "randomSalt"; +string hash1 = "hello world".GetMD5WithSalt(salt); +// or specific encoding type +string hash2 = "hello world".GetMD5WithSalt(salt, EncodingType.UTF8); +``` +```csharp +byte[] byteArray = Encoding.UTF8.GetBytes("Hello, World!"); +byte[] saltBytes = Encoding.UTF8.GetBytes("randomSalt"); +string hash = byteArray.GetMD5WithSalt(saltBytes); +``` +```csharp +BrasilModel obj = new BrasilModel() { Id = 1, Details = "Maior país da América do Sul" }; +string salt = "randomSalt"; +string hash = obj.GetMD5WithSalt(salt); +``` +To number you can use: +```csharp +string salt = "randomSalt"; +string hash = myNumber.ToString().GetMD5WithSalt(salt); +``` + ## Installation You can install the library via NuGet package manager by searching for MD5 or by executing the following command in the Package Manager Console: