1
0
Files
OAiP-Presnyakov_Ilya-Labora…/Services/PasswordHasher.cs
Debug_pro fb13e5a20a upload
2026-06-07 18:19:53 +03:00

78 lines
2.1 KiB
C#

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);
}
}