I'm looking to allow bcrypt support in my 开发者_JS百科authentication library. One of the problems right now is that I assume that the hasher will be of type HashAlgorithm
. Bcrypt.net does not implement this class. Also, it's sealed so I would have to make my own branch off of it and modify it myself. Are there any better alternatives that already implement HashAlgorithm?
Try this:
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);
}
}
Usage:
BCryptHasher hasher = new BCryptHasher();
string pw = "abc";
string hash = Encoding.UTF8.GetString(hasher.ComputeHash(Encoding.UTF8.GetBytes(pw)));
Also, I added a helper Verify method so you can verify that the password and hash match, but you can eliminate this if you just call the default BCrypt.Verify.
bool matches = hasher.Verify(pw, hash);
I added some extra properties so you can pass in a pre-computed salt or a work factor to generate a new salt before you do the hash:
string pw = "abc";
hasher.Salt = "$2a$06$If6bvum7DFjUnE9p2uDeDu";
string hash = Encoding.UTF8.GetString(hasher.ComputeHash(Encoding.UTF8.GetBytes(pw)));
I tried it with the BCrypt test case "abc" with a salt of "$2a$06$If6bvum7DFjUnE9p2uDeDu" and got the correct hash.
精彩评论