Started to try and organize all the authentication code.
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace SecureCore.Authentication
|
||||
{
|
||||
public static class ByteGenerator
|
||||
{
|
||||
public static void GetRandomBytes(ref byte[] bytes)
|
||||
{
|
||||
using var rng = RandomNumberGenerator.Create();
|
||||
rng.GetBytes(bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
|
||||
|
||||
namespace SecureCore.Authentication
|
||||
{
|
||||
public class PasswordManager
|
||||
{
|
||||
private static string ConnectionString = @"Server=DESKTOP-OEDDVKC\SQLEXPRESS;Database=main;Integrated Security=true;";
|
||||
|
||||
public PasswordManager()
|
||||
{
|
||||
}
|
||||
|
||||
public static (string Hash, string Salt) HashPassword(string password)
|
||||
{
|
||||
var salt = new byte[Settings.SaltSize];
|
||||
|
||||
ByteGenerator.GetRandomBytes(ref salt);
|
||||
|
||||
return (GetPasswordHash(password, salt), Convert.ToBase64String(salt));
|
||||
}
|
||||
|
||||
public static bool PasswordIsValid(string password, string salt, string passwordHash)
|
||||
{
|
||||
var saltBytes = Convert.FromBase64String(salt);
|
||||
|
||||
return passwordHash == GetPasswordHash(password, saltBytes);
|
||||
}
|
||||
|
||||
public static (string PasswordHash, string SaltHash) GetUserPasswordHash(int userId)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
using (var command = new SqlCommand("SELECT [Password Hash], [Salt Hash] FROM Login WHERE [User Key] = @UserId", connection))
|
||||
{
|
||||
command.Parameters.AddWithValue("UserId", userId);
|
||||
|
||||
connection.Open();
|
||||
|
||||
var reader = command.ExecuteReader();
|
||||
|
||||
if (!reader.HasRows) throw new MissingFieldException("No login records exist for this user.");
|
||||
|
||||
reader.Read();
|
||||
|
||||
return (reader["Password Hash"].ToString(), reader["Salt Hash"].ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetPasswordHash(string password, byte[] salt)
|
||||
{
|
||||
return Convert.ToBase64String(KeyDerivation.Pbkdf2(password, salt, Settings.KeyType, Settings.Iterations, Settings.KeySize));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SecureCore.Authentication
|
||||
{
|
||||
public class SessionManager
|
||||
{
|
||||
public static string CreateSessionToken()
|
||||
{
|
||||
var token = new byte[Settings.SessionKeySize];
|
||||
|
||||
ByteGenerator.GetRandomBytes(ref token);
|
||||
|
||||
return Convert.ToBase64String(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
|
||||
|
||||
namespace SecureCore.Authentication
|
||||
{
|
||||
public static class Settings
|
||||
{
|
||||
public static int Iterations { get; } = 100000;
|
||||
public static KeyDerivationPrf KeyType { get; } = KeyDerivationPrf.HMACSHA512;
|
||||
public static int KeySize { get; } = 512 / 8;
|
||||
public static int SaltSize { get; } = 128 / 8; //128 bit salt
|
||||
public static int SessionKeySize { get; } = 32; //32 bytes
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user