You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
PortfolioLink/backend/Hasher.cs

138 lines
5.3 KiB

using Isopoh.Cryptography.Argon2;
using Isopoh.Cryptography.SecureArray;
using System.Security.Cryptography;
using System.Text;
using Chaos.NaCl;
namespace Hasher
{
/// <summary>
/// A utility class for generating and verifying Argon2 hashes.
/// </summary>
public static class Argon2dHasher
{
private static readonly RandomNumberGenerator Rng = RandomNumberGenerator.Create();
/// <summary>
/// Generates an Argon2 hash for the given password and salt.
/// </summary>
/// <param name="password">The password to hash.</param>
/// <param name="salt">A random salt to use for the hash. If null, a new 16-byte salt will be generated.</param>
/// <returns>The generated Argon2 hash as a string.</returns>
public static string GenerateArgon2Hash(string password, byte[]? salt)
{
if (salt == null)
{
salt = new byte[16];
}
byte[] pwBytes = Encoding.UTF8.GetBytes(password);
// Generate a random salt
Rng.GetBytes(salt);
var config = new Argon2Config
{
Type = Argon2Type.DataIndependentAddressing,
Version = Argon2Version.Nineteen,
TimeCost = 6,
Lanes = 3,
Threads = Environment.ProcessorCount - 1, // higher than "Lanes" doesn't help (or hurt)
Password = pwBytes,
Salt = salt,
};
var argon2 = new Argon2(config);
string hashString;
using(SecureArray<byte> hashA = argon2.Hash())
{
hashString = config.EncodeString(hashA.Buffer);
}
return hashString;
}
/// <summary>
/// Verifies that a given password matches an Argon2 hash.
/// </summary>
/// <param name="password">The password to check.</param>
/// <param name="hash">The Argon2 hash to check against.</param>
/// <returns>True if the password matches the hash, false otherwise.</returns>
public static bool VerifyArgon2Hash(string password, string hash)
{
byte[] pwBytes = Encoding.UTF8.GetBytes(password);
var valid = Argon2.Verify(hash, pwBytes);
return valid;
}
}
/// <summary>
/// The FingerPrinter class provides methods to generate and hash fingerprints.
/// </summary>
public class FingerPrinter
{
/// <summary>
/// Helper function to generate a random string of a given length.
/// </summary>
/// <param name="length">The length of the string to generate.</param>
/// <returns>A random string of the specified length.</returns>
private static string GetRandomString(int length)
{
var r = new Random();
return new String(Enumerable.Range(0, length).Select(n => (Char)(r.Next(32, 127))).ToArray());
}
/// <summary>
/// Helper function to hash a fingerprint using SHA-256.
/// </summary>
/// <param name="fingerprint">The fingerprint to hash.</param>
/// <returns>The SHA-256 hash of the input fingerprint as a base64-encoded string.</returns>
private static string HashFingerprint(string fingerprint)
{
using var sha256 = SHA256.Create();
var hashedFingerprint = sha256.ComputeHash(Encoding.UTF8.GetBytes(fingerprint));
return Convert.ToBase64String(hashedFingerprint);
}
/// <summary>
/// Returns an array containing a randomly generated plain text fingerprint and its hashed value.
/// </summary>
/// <param name="length">The length of the plain text fingerprint to generate (default is 32).</param>
/// <returns>An array of two strings: the plain text fingerprint and its hashed value.</returns>
public static string[] GetFingerprintSet(int length = 32)
{
string plainText = GetRandomString(length);
string hashed = HashFingerprint(plainText);
return new string[] { plainText, hashed };
}
/// <summary>
/// Validates whether the specified fingerprint matches the provided hashed fingerprint using SHA256 encryption.
/// </summary>
/// <param name="fingerprint">The fingerprint string to be validated.</param>
/// <param name="fpHash">The hashed fingerprint to be compared against the fingerprint.</param>
/// <returns>Returns a boolean value indicating whether the fingerprint and its hash match or not.</returns>
public static bool ValidateFingerpint(string fingerprint, string fpHash)
{
using var sha256 = SHA256.Create();
var newFpHash = sha256.ComputeHash(Encoding.UTF8.GetBytes(fingerprint));
return Convert.ToBase64String(newFpHash) == fpHash ;
}
}
public class KeyHelper
{
private static byte[] FromBase64String(string input)
{
return Convert.FromBase64String(input);
}
public static bool validateSignature(string signature, string message, string publicKey)
{
return Ed25519.Verify(FromBase64String(signature), Encoding.UTF8.GetBytes(message), FromBase64String(publicKey));
}
}
}