upload
This commit is contained in:
77
Services/PasswordHasher.cs
Normal file
77
Services/PasswordHasher.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Konscious.Security.Cryptography;
|
||||
|
||||
namespace SimpleWiki.Services;
|
||||
|
||||
public static class PasswordHasher
|
||||
{
|
||||
private const int Iterations = 3;
|
||||
private const int MemorySizeKb = 65536;
|
||||
private const int Parallelism = 1;
|
||||
private const int SaltLength = 16;
|
||||
private const int HashLength = 32;
|
||||
|
||||
public static string HashPassword(string password)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(password))
|
||||
{
|
||||
throw new ArgumentException("Пароль пустой.");
|
||||
}
|
||||
|
||||
var salt = RandomNumberGenerator.GetBytes(SaltLength);
|
||||
|
||||
using var argon2 = new Argon2id(Encoding.UTF8.GetBytes(password))
|
||||
{
|
||||
Salt = salt,
|
||||
Iterations = Iterations,
|
||||
DegreeOfParallelism = Parallelism,
|
||||
MemorySize = MemorySizeKb
|
||||
};
|
||||
|
||||
var hash = argon2.GetBytes(HashLength);
|
||||
var combined = new byte[SaltLength + HashLength];
|
||||
|
||||
Buffer.BlockCopy(salt, 0, combined, 0, SaltLength);
|
||||
Buffer.BlockCopy(hash, 0, combined, SaltLength, HashLength);
|
||||
|
||||
return Convert.ToBase64String(combined);
|
||||
}
|
||||
|
||||
public static bool VerifyPassword(string password, string hashPassword)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(password) || string.IsNullOrWhiteSpace(hashPassword))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
byte[] combined;
|
||||
try
|
||||
{
|
||||
combined = Convert.FromBase64String(hashPassword);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (combined.Length < SaltLength + HashLength)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var salt = combined.Take(SaltLength).ToArray();
|
||||
var originalHash = combined.Skip(SaltLength).Take(HashLength).ToArray();
|
||||
|
||||
using var argon2 = new Argon2id(Encoding.UTF8.GetBytes(password))
|
||||
{
|
||||
Salt = salt,
|
||||
Iterations = Iterations,
|
||||
DegreeOfParallelism = Parallelism,
|
||||
MemorySize = MemorySizeKb
|
||||
};
|
||||
|
||||
var newHash = argon2.GetBytes(HashLength);
|
||||
return CryptographicOperations.FixedTimeEquals(originalHash, newHash);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user