.Net реализация bcrypt, которая реализует HashAlgorithm? - PullRequest
4 голосов
/ 13 апреля 2011

Я хочу разрешить поддержку bcrypt в моей библиотеке аутентификации.Одной из проблем сейчас является то, что я предполагаю, что хеш будет иметь тип HashAlgorithm.Bcrypt.net не реализует этот класс.Кроме того, он запечатан, так что мне придется сделать из него собственную ветку и изменить его самостоятельно.Есть ли лучшие альтернативы, которые уже реализуют HashAlgorithm?

1 Ответ

6 голосов
/ 27 июня 2011

Попробуйте это:

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» и получил правильный хеш.

...