Files
raven/server/AyaNova/util/Hasher.cs
2021-10-21 19:04:14 +00:00

77 lines
2.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
namespace AyaNova.Util
{
public static class Hasher
{
public static string hash(string Salt, string Password)
{
//adapted from here:
//https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/consumer-apis/password-hashing
string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: Password,
salt: Convert.FromBase64String(Salt),
prf: KeyDerivationPrf.HMACSHA512,
iterationCount: 10000,
numBytesRequested: 512 / 8));
return hashed;
}
//Generate salt
/*
Used for many things:
DBID, JWT secret key when none provided, User Salt for login / password,
temporary 2fa codes, download tokens,
temporary user pw / login when newly created and haven't been set yet
*/
public static string GenerateSalt()
{
var salt = new byte[32];
var random = RandomNumberGenerator.Create();
random.GetNonZeroBytes(salt);
return Convert.ToBase64String(salt);
}
public static string GetRandomAlphanumericString(int length)
{
const string alphanumericCharacters = "0123456789abcdefghijkmnopqrstuvwxyz";
return GetRandomString(length, alphanumericCharacters);
}
public static string GetRandomString(int length, IEnumerable<char> characterSet)
{
if (length < 0)
throw new ArgumentException("length must not be negative", "length");
if (length > int.MaxValue / 8)
throw new ArgumentException("length is too big", "length");
if (characterSet == null)
throw new ArgumentNullException("characterSet");
var characterArray = characterSet.Distinct().ToArray();
if (characterArray.Length == 0)
throw new ArgumentException("characterSet must not be empty", "characterSet");
var bytes = new byte[length * 8];
RandomNumberGenerator.Create().GetBytes(bytes);
var result = new char[length];
for (int i = 0; i < length; i++)
{
ulong value = BitConverter.ToUInt64(bytes, i * 8);
result[i] = characterArray[value % (uint)characterArray.Length];
}
return new string(result);
}
}//eoc
}//eons