zetetic has a pretty sweet encryption library that includes support for bcrypt2. It looks like it should be straightforward enough to incorporate into an ASP.NET Membership Provider (in fact, instructions for the default provider can be found here). I am using an NHibernate Membership Provider (found here) which seems to hard code the SHA1 hash format in it’s EncodePassword function. My question is, how should this be adapted to work with BCrypt2 (specifically Zetetic’s wrapper). This is something I greatly fear getting wrong, and I’m reluctant to take a stab at it myself lest it should “work” but have some hidden flaw that I am not qualified to find.
private string EncodePassword(string password)
{
string encodedPassword = password;
switch (PasswordFormat)
{
case MembershipPasswordFormat.Clear:
break;
case MembershipPasswordFormat.Encrypted:
encodedPassword =
Convert.ToBase64String(EncryptPassword(Encoding.Unicode.GetBytes(password)));
break;
case MembershipPasswordFormat.Hashed:
HMACSHA1 hash = new HMACSHA1();
hash.Key = HexToByte(_machineKey.ValidationKey);
encodedPassword =
Convert.ToBase64String(hash.ComputeHash(Encoding.Unicode.GetBytes(password)));
break;
default:
throw new ProviderException("Unsupported password format.");
}
return encodedPassword;
}
Are you modifying the NHibernate-based membership provider, or stuck using it out of the box? If the latter, it doesn’t look like there’s any extensibility.
The ASP.NET SqlMembershipProvider works by accepting the name of a hash algorithm, conjures an instance via HashAlgorithm.Create(name) and then behaves a little differently if the algorithm type turns out to be a KeyedHashAlgorithm or regular (non-keyed) HashAlgorithm. The Zetetic.Security package is just providing a little bit of glue to make BCrypt and PBKDF2 compatible with that model.
The sample code from NHMembershipProvider can’t take advantage of that because it’s very directly relying on HMACSHA1. I’d note that HMACSHA1 is not a secure algorithm for this purpose, nor is using a static salt for all users acceptable (it’s scarcely better than no salt). The app ValidationKey and HMACSHA1 are meant for message integrity only.
Here’s a sample: