-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
fe4d271
commit 1f55e72
Showing
7 changed files
with
232 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 17 | ||
VisualStudioVersion = 17.11.35327.3 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HashingHandlerSamples", "src\HashingHandlerSamples.csproj", "{8D2696BC-FB37-4E71-8FDA-DC741EC9D972}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{8D2696BC-FB37-4E71-8FDA-DC741EC9D972}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{8D2696BC-FB37-4E71-8FDA-DC741EC9D972}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{8D2696BC-FB37-4E71-8FDA-DC741EC9D972}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{8D2696BC-FB37-4E71-8FDA-DC741EC9D972}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {5F4650F6-A119-4F26-A645-C2F72B5881C4} | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="HashingHandler" Version="1.7.0" /> | ||
<PackageReference Include="HashingHandler.Formats.String" Version="1.3.0" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
using HashingHandler; | ||
using HashingHandler.Formats.String; | ||
using System.IO.Hashing; | ||
using System.Security.Cryptography; | ||
using System.Text; | ||
|
||
namespace HashingHandlerSamples; | ||
|
||
class Program | ||
{ | ||
static void Main(string[] args) | ||
{ | ||
// Synchronous Only | ||
/* | ||
IHashingAlgorithm<string> sha256 = new SHA256Hasher(); | ||
IHashingAlgorithm<string> xxh3 = new XXH3Hasher(); | ||
IHashingAlgorithm<string> xor = new XORHash(); | ||
*/ | ||
|
||
// Synchronous and Asynchronous | ||
IHashingAlgorithmAsync<string> sha256 = new SHA256Hasher(); | ||
IHashingAlgorithmAsync<string> xxh3 = new XXH3Hasher(); | ||
IHashingAlgorithmAsync<string> xor = new XORHash(); | ||
|
||
// Hash provider of string data | ||
IHashingProvider<string> provider = new StringHashProvider(Encoding.UTF8); | ||
|
||
// Synchronous Only | ||
/* | ||
IHashVerifier<string> stringVerifier = new StringHashVerifier(); | ||
*/ | ||
|
||
// Synchronous and Asynchronous | ||
IHashVerifierAsync<string> stringVerifier = new StringHashVerifier(); | ||
|
||
// Base64 encoding of hash bytes | ||
IStringEncodingAsync base64 = new Base64Hashes(); | ||
|
||
while (true) | ||
{ | ||
Console.Write("Enter some text: "); | ||
string text = Console.ReadLine() ?? string.Empty; | ||
|
||
// Sha256 | ||
string hashSha256 = sha256.ComputeHash(text, provider); | ||
bool matchSha = stringVerifier.VerifyHash(text, hashSha256, sha256); // True, hashes match | ||
|
||
// Sha256 in base64 | ||
string hashSha256Base64 = sha256.ComputeHash(text, provider, encoding: base64); | ||
bool matchShaBase64 = stringVerifier.VerifyHash(text, hashSha256Base64, sha256, encoding: base64); // True, hashes match | ||
|
||
// Xxh3 | ||
string hashXxh3 = xxh3.ComputeHash(text, provider); | ||
bool matchXxh3 = stringVerifier.VerifyHash(text, hashXxh3, xxh3); // True, hashes match | ||
|
||
// XOR | ||
string hashXor = xor.ComputeHashAsync(text, provider).GetAwaiter().GetResult(); | ||
bool matchXor = stringVerifier.VerifyHash(text, hashXor, xor); // True, hashes match | ||
|
||
// False, because SHA256 and XXH3 are different algorithms that produce different hashes for the same data. | ||
bool testFail = stringVerifier.VerifyHash(text, hashXxh3, sha256); | ||
|
||
// False, because sha256 is not encoded in base64 | ||
bool testFail2 = stringVerifier.VerifyHash(text, hashSha256, sha256, base64); | ||
|
||
Console.WriteLine(); | ||
Console.WriteLine($"SHA256: {hashSha256} {matchSha}"); | ||
Console.WriteLine($"SHA256 Base64: {hashSha256Base64} {matchShaBase64}"); | ||
Console.WriteLine($"XXH3: {hashXxh3} {matchXxh3}"); | ||
Console.WriteLine($"XOR: {hashXor} {matchXor}"); | ||
Console.WriteLine($"Fail test success: {!testFail} {!testFail2}"); | ||
Console.WriteLine(); | ||
} | ||
} | ||
} | ||
|
||
class Base64Hashes : StringEncodingBase | ||
{ | ||
public override string ConvertToString(byte[] bytes) | ||
{ | ||
return Convert.ToBase64String(bytes); | ||
} | ||
} | ||
|
||
class SHA256Hasher : HashingCrypto<string> | ||
{ | ||
protected override HashAlgorithm GetAlgorithm() | ||
{ | ||
return SHA256.Create(); // Returns new SHA256 object | ||
} | ||
} | ||
|
||
class XXH3Hasher(long seed = 0) : HashingNonCrypto<string> | ||
{ | ||
private readonly long _seed = seed; | ||
|
||
protected override NonCryptographicHashAlgorithm GetAlgorithm() | ||
{ | ||
return new XxHash3(_seed); | ||
} | ||
} | ||
|
||
class XORHash : HashingAlgorithmBase<string> | ||
{ | ||
protected override byte[] ComputeHash(byte[] bytes) | ||
{ | ||
// Specify the length of the payload to be hashed. | ||
int payloadLength = bytes.Length; // Let's hash the entire payload. | ||
|
||
// Specify the length of the returned hash. | ||
int hashLength = 8; // 8 bytes, 16 characters | ||
|
||
// Initialize result array to hold the hash of specified length | ||
byte[] result = new byte[hashLength]; | ||
|
||
// Perform XOR on the bytes, distributing across each position in result | ||
for (int i = 0; i < payloadLength; i++) | ||
{ | ||
result[i % hashLength] ^= bytes[i]; | ||
} | ||
|
||
return result; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# Verifiers | ||
|
||
Verifiers in HashingHandler implement `IHashVerifier<T>` or `IHashVerifierAsync<T>`. Implementers of `IHashVerifierAsync<T>` also implement `IHashVerifier<T>`. | ||
|
||
## Variants | ||
|
||
### IHashVerifier | ||
|
||
`IHashVerifier<T>` is used for accessing hash verifier classes. These classes allow for the verification of data against expected hashes. | ||
|
||
### IHashVerifierAsync | ||
|
||
`IHashVerifierAsync<T>` allows the asynchronous use of `IHashVerifier<T>`. It implements `IHashVerifier<T>`, so objects capable of asynchronous verification are also able to leverage synchronous methods. | ||
|
||
### HashVerifierBase | ||
|
||
`HashVerifierBase<T>` is the primary base class for implementations of both `IHashVerifierAsync<T>` and `IHashVerifier<T>`, providing methods for both. It provides support for both synchronous and asynchronous hash verification, using `public` methods `bool VerifyHash()` and `Task<bool> VerifyHashAsync()`. | ||
|
||
### HashVerifierGeneric | ||
|
||
`HashVerifierGeneric<T>` provides a generic implementation of `HashVerifierBase<T>`. It can be constructed with the required `IHashingProvider<T>` and optional `StringComparison` setting for the comparison of the hash strings. | ||
|
||
## Examples | ||
|
||
If you'd like to provide type-flexible hash verification, use an implementation of `HashVerifierBase<T>` or a `HashVerifierGeneric<T>` rather than making your own implementation of `IHashVerifier<T>` or `IHashVerifierAsync<T>`. Only make your own `IHashVerifier<T>` or `IHashVerifierAsync<T>` if you'd like to use a different string comparison method than [`string.Equals()`](https://learn.microsoft.com/dotnet/api/system.string.equals) for hash strings. | ||
|
||
### Implementing `HashVerifierGeneric<T>` | ||
|
||
`HashVerifierGeneric<T>` is a non-abstract class implementation of the abstract class `HashVerifierBase<T>`, meaning you can instantiate it and re-use it for verifications of the same data type, `T`. | ||
|
||
``` | ||
public class MyClass | ||
{ | ||
public static bool VerifyHash(DateTime data, string expectedHash) | ||
{ | ||
// Create an IHashingProvider<DateTime> called 'provider'. | ||
IHashVerifier<DateTime> verifier = CreateVerifier(provider); | ||
// Create an IHashingAlgorithm<DateTime> called 'algorithm'. | ||
// Optionally, create an IStringEncoding called 'encoding' to use for hash byte encoding. | ||
// Not doing this will interpret the hash calculation as Hexadecimal string by default. | ||
return verifier.VerifyHash(data, expectedHash, algorithm, encoding) // encoding is an optional parameter. | ||
} | ||
// could also return IHashVerifier<DateTime> because HashVerifierGeneric is IHashVerifierAsync. | ||
private static IHashVerifier<DateTime> CreateVerifier(IHashingProvider<DateTime> provider) | ||
{ | ||
return new HashVerifierGeneric(provider); // StringComparison is an optional parameter for the constructor. | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters