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

64 lines
2.6 KiB
C#

using System.Security.Cryptography;
using System.Text;
using AyCode.Core.Consts;
using AyCode.Core.Extensions;
using AyCode.Utils.Extensions;
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
namespace AyCode.Core.Helpers
{
public class PasswordHasher
{
public static string HashPassword(string? password, string? dynamicSalt = null)
{
if (string.IsNullOrWhiteSpace(password)) throw new ArgumentNullException(nameof(password));
// 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)
{
if (string.IsNullOrWhiteSpace(password)) return false;
// Extract the salt and hashed password from the combined hash
var parts = hashedPassword.Split('$');
if (parts.Length != 5) return false;
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.
public static string GenerateDynamicSalt(Guid userId)
=> userId.ToString("N").ToLower().Reverse().MixCharacters(AcConst.ProjectSalt);
//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();
}
}