Files
Backend-Api/0_Framework/Application/PasswordHasher.cs
2024-07-05 21:36:15 +03:30

97 lines
2.3 KiB
C#

using System;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using Microsoft.Extensions.Options;
namespace _0_Framework.Application;
public class PasswordHasher : IPasswordHasher
{
private const int SaltSize = 16; // 128 bit
private const int KeySize = 32; // 256 bit
public PasswordHasher(IOptions<HashingOptions> options)
{
Options = options.Value;
}
private HashingOptions Options { get; }
public string Hash(string password)
{
using var algorithm = new Rfc2898DeriveBytes(password, SaltSize, Options.Iterations, HashAlgorithmName.SHA256);
var key = Convert.ToBase64String(algorithm.GetBytes(KeySize));
var salt = Convert.ToBase64String(algorithm.Salt);
return $"{Options.Iterations}.{salt}.{key}";
}
public (bool Verified, bool NeedsUpgrade) Check(string hash, string password)
{
var parts = hash.Split('.', 3);
if (parts.Length != 3)
{
return (false, false);
}
var iterations = Convert.ToInt32(parts[0]);
var salt = Convert.FromBase64String(parts[1]);
var key = Convert.FromBase64String(parts[2]);
var needsUpgrade = iterations != Options.Iterations;
using var algorithm = new Rfc2898DeriveBytes(password, salt, iterations, HashAlgorithmName.SHA256);
var keyToCheck = algorithm.GetBytes(KeySize);
var verified = keyToCheck.SequenceEqual(key);
return (verified, needsUpgrade);
}
#region Mahan
public string SlugHasher(long slug)
{
try
{
var test = slug.ToString();
UTF8Encoding encoder = new UTF8Encoding();
byte[] hashedDataBytes = encoder.GetBytes(test);
return Convert.ToBase64String(hashedDataBytes);
}
catch
{
return "";
}
}
public long SlugDecrypt(string slug)
{
if (string.IsNullOrWhiteSpace(slug) || slug.Trim() == "0")
{
return 0;
}
try
{
byte[] bytes = Convert.FromBase64String(slug);
string result = System.Text.Encoding.UTF8.GetString(bytes);
return long.Parse(result);
}
catch
{
return -1;
}
}
#endregion
}