AyCode.Core/AyCode.Utils/Helpers/PasswordHasher.cs

52 lines
2.1 KiB
C#

using Microsoft.AspNetCore.Cryptography.KeyDerivation;
using System.Security.Cryptography;
using System.Text;
using AyCode.Core.Extensions;
using AyCode.Utils.Extensions;
namespace AyCode.Utils.Helpers
{
public class PasswordHasher
{
public static string HashPassword(string password, string? dynamicSalt = null)
{
// Generate a random salt
var salt = new byte[16];
using (var rng = RandomNumberGenerator.Create()) rng.GetBytes(salt);
// Hash the password with the salt
var hashedPassword = GenerateHashedPassword(password, salt, dynamicSalt);
// Combine the salt and hashed password
var combinedHash = $"$bcrypt$v=1$salt={Convert.ToBase64String(salt)}$hash={hashedPassword}";
return combinedHash;
}
public static bool VerifyPassword(string password, string hashedPassword, string? dynamicSalt = null)
{
// Extract the salt and hashed password from the combined hash
var parts = hashedPassword.Split('$');
var salt = Convert.FromBase64String(parts[3].Replace("salt=", string.Empty));
var storedHash = parts[4].Replace("hash=", string.Empty);
return storedHash == GenerateHashedPassword(password, salt, dynamicSalt);
}
private static string GenerateHashedPassword(string password, byte[] salt, string? dynamicSalt)
=> Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: password,
salt: GenerateFinallySalt(salt, dynamicSalt),
prf: KeyDerivationPrf.HMACSHA512,
iterationCount: 10000,
numBytesRequested: 32));
//SEMMILYEN KÖRÜLMÉNYEK KÖZÖTT SE VÁLTOZTASD MEG METÓDUS LOGIKÁJÁT!!! Különben senki sem fog tudni Login-olni! - J.
private static byte[] GenerateFinallySalt(byte[] salt, string? dynamicSalt)
=> SHA256.HashData(string.IsNullOrWhiteSpace(dynamicSalt) ? salt : Encoding.ASCII.GetBytes(Convert.ToBase64String(salt).Reverse().MixCharacters(dynamicSalt))).Take(16).ToArray();
}
}