68 lines
2.3 KiB
C#
68 lines
2.3 KiB
C#
using System;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
|
|
namespace ChronoFlow.Security
|
|
{
|
|
/// <summary>
|
|
/// Diese Klasse bietet Funktionen zum sicheren Hashen und Überprüfen von Passwörtern.
|
|
/// </summary>
|
|
public static class PasswordHasher
|
|
{
|
|
/// <summary>
|
|
/// Erstellt einen sicheren Hash aus einem Passwort unter Verwendung von PBKDF2.
|
|
/// </summary>
|
|
/// <param name="password">Das Klartextpasswort</param>
|
|
/// <returns>Ein kombinierter Hash-String (Salt + Hash)</returns>
|
|
public static string HashPassword(string password)
|
|
{
|
|
using var rng = RandomNumberGenerator.Create();
|
|
byte[] salt = new byte[16];
|
|
rng.GetBytes(salt);
|
|
|
|
var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 100_000, HashAlgorithmName.SHA256);
|
|
byte[] hash = pbkdf2.GetBytes(32);
|
|
|
|
// Kombiniere Salt + Hash in einen String (Base64-encodiert)
|
|
byte[] hashBytes = new byte[48];
|
|
Array.Copy(salt, 0, hashBytes, 0, 16);
|
|
Array.Copy(hash, 0, hashBytes, 16, 32);
|
|
|
|
return Convert.ToBase64String(hashBytes);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Überprüft, ob ein Passwort zu einem gegebenen Hash passt.
|
|
/// </summary>
|
|
/// <param name="password">Das eingegebene Klartextpasswort</param>
|
|
/// <param name="storedHash">Der gespeicherte kombinierte Hash (Base64, Salt + Hash)</param>
|
|
/// <returns>True, wenn das Passwort stimmt, sonst false</returns>
|
|
public static bool VerifyPassword(string password, string storedHash)
|
|
{
|
|
try
|
|
{
|
|
byte[] hashBytes = Convert.FromBase64String(storedHash);
|
|
|
|
byte[] salt = new byte[16];
|
|
Array.Copy(hashBytes, 0, salt, 0, 16);
|
|
|
|
var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 100_000, HashAlgorithmName.SHA256);
|
|
byte[] hash = pbkdf2.GetBytes(32);
|
|
|
|
for (int i = 0; i < 32; i++)
|
|
{
|
|
if (hashBytes[i + 16] != hash[i])
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
// Falls der gespeicherte Hash beschädigt oder kein Base64 ist
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|