2

I need to create some hashing classes (C#) for a login service where (unfortunately) the passwords needs to be stored in SQL server database. In the past I've been using BCrypt or PBKDF2 but there are some concerns. This is for an enterprise level solution running in the US. I see 3 valid paths that I'd like you to comment on.

BCrypt: Is not a NIST standard and that would probably be required for some customers. I'm also reluctant to use BCrypt for enterprise level software because I need something that is backed by a large company or some dedicated developers. All I can find are some (old) implementations that are maintained by one guy in his spare time. Should that not cause some concerns? I mean while the algo it self is great, the implementation might not be. And surely has to be maintained.

What are the 2016 iteration (workfactor) recommendation - 12?

PBKDF2: The only solution I can find for C#, is Microsofts "PasswordHasher" (or similar Rfc2898DeriveBytes implementation). The released version is using HMAC SHA1 with 1000 iterations. This seems invalid in 2016. There is a newer version here, but that seems to be a prerelease in Nuget. In any case that is also just using HMAC SHA256 with a static iteration count of 10000. Where I would expect this to be at least 256000 in 2016. Also if you look at the code the implementation calls some Win8Pbkdf2Provider behind the scenes which tends to be BCrypt derivative (making my NIST requirement hard anyways).

SHA1 + AES: An alternative approach would be to just go with standard Rfc2898DeriveBytes using HMAC SHA1 and then using AES to encrypt the database values - storing the AES key on disk. I like this approach the best actually but if you search these things, that solution never surfaces so I might be be missing something...

What do you guys recommend? What do you do when looking into securing enterprise level software?

Anders
  • 65,052
  • 24
  • 180
  • 218
Werner
  • 121
  • 1
  • 3
    By "enterprise-level", do you simply mean "high standards"? Being "enterprise" usually indicates the size and scope of implementation. You seem to be asking about expectations and specification that are not unique to large organizations. Can you expand what you mean by "enterprise"? – schroeder Sep 05 '16 at 09:12
  • 2
    I guess I am also confused about what your specification is. Do you need NIST, or better than NIST? Do you need to pass an audit? If so, which one? Are you looking for industry standard, or better than industry standard? Are you looking for "the absolute best, most secure option, and I want to prove it"? – schroeder Sep 05 '16 at 09:18
  • @schroeder No specific requirement for NIST but customers in US expected. By enterprise I mean large scale (> 50.000 users) and accounts that can access data that are of personal nature. Several regulativs involved in the handling of that data - but the hashing of the pwds are not specified. Most customers will have some AD/ADFS instead - my specific use case is trying to investigate solution for that 1% that require us to handle the authentication. The solution will be audited when we start implementing - but we are in the investigating phase and the audit company have not yet been found. – Werner Sep 05 '16 at 09:51
  • Ok, that makes things a little clearer. The size and "enterprise-ness" is not important. You need to pass future customer audits on design when the customers are US-based and there is personal data involved. Those are the relevant details. I'd recommend editing your question to incorporate these details. (I'd also ditch the 'enterprise' thing) – schroeder Sep 05 '16 at 10:00

2 Answers2

3

What are your actual requirements? "Enterprise level" doesn't say much, at least no more than it will be a large project. If NIST is a requirement, then PBKDF2 is all you've got. From a security perspective, I would recommend bcrypt, as it is slightly more secure than PBKDF2 which is based on SHA variants. bcrypt itself has baked long enough to be a good alternative to PBKDF2, even though the NIST doesn't say anything about it (yet).

When it comes to implementation, you really should use a well-established library. You don't want to manually check the implementation details and neither should you. A quick search revealed that there are several bcrypt implementations for C# that are well supported in the C# community.

For more details about PBKDF2 vs bcrypt also see the answer by Thomas Pornin.

Update

I wouldn't go with the SHA1+AES option. Doing this will not actually resolved the problem, but only mitigate the risks for certain types of attacks. Still if the application somehow were to leak database contents, you can only trust on SHA1. It feels to me like a hack, and the last thing you want is to cook up something yourself.

Yorick de Wid
  • 3,356
  • 15
  • 22
2

I can see no reason not to use BCrypt, there is a decent library called BCrypt.Net.

The security comes from the algorithm, not from the implementation, so you can double check the result directly with other wellknown libraries. What can go wrong is the generation of a secure random salt. If you look at the source code though, you can see that they use the cryptographic random number generator from the DotNet library, so this is done correctly.

martinstoeckli
  • 5,189
  • 2
  • 27
  • 32