97 lines
2.3 KiB
C#
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
|
|
|
|
} |