77 lines
2.6 KiB
C#
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 Sockeye.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 |