Попробуйте это:
public class BCryptHasher : HashAlgorithm
{
private MemoryStream passwordStream = null;
protected override void HashCore(byte[] array, int ibStart, int cbSize)
{
if (passwordStream == null || Salt == null)
Initialize();
passwordStream.Write(array, ibStart, cbSize);
}
protected override byte[] HashFinal()
{
passwordStream.Flush();
// Get the hash
return Encoding.UTF8.GetBytes(BCrypt.Net.BCrypt.HashPassword(Encoding.UTF8.GetString(passwordStream.ToArray()), Salt));
}
public override void Initialize()
{
passwordStream = new MemoryStream();
// Set up salt
if (Salt == null)
{
if (WorkFactor == 0)
Salt = BCrypt.Net.BCrypt.GenerateSalt();
else
Salt = BCrypt.Net.BCrypt.GenerateSalt(WorkFactor);
}
}
public int WorkFactor { get; set; }
public string Salt { get; set; }
public bool Verify(string plain, string hash)
{
return BCrypt.Net.BCrypt.Verify(plain, hash);
}
}
Использование:
BCryptHasher hasher = new BCryptHasher();
string pw = "abc";
string hash = Encoding.UTF8.GetString(hasher.ComputeHash(Encoding.UTF8.GetBytes(pw)));
Кроме того, я добавил вспомогательный метод Verify, чтобы вы могли проверить, совпадают ли пароль и хеш, но вы можете устранить это, если просто вызовете BCrypt.Verify по умолчанию.
bool matches = hasher.Verify(pw, hash);
Я добавил некоторые дополнительные свойства, чтобы вы могли передать предварительно вычисленную соль или рабочий фактор для генерации новой соли до того, как вы сделаете хеш:
string pw = "abc";
hasher.Salt = "$2a$06$If6bvum7DFjUnE9p2uDeDu";
string hash = Encoding.UTF8.GetString(hasher.ComputeHash(Encoding.UTF8.GetBytes(pw)));
Я попробовал это с контрольным примером BCrypt «abc» с солью «$ 2a $ 06 $ If6bvum7DFjUnE9p2uDeDu» и получил правильный хеш.