I've been told by a CISSP that the .NET class Rfc2898DeriveBytes would not pass a security audit today because it still uses SHA1. It's reliance on SHA1 - even with the iterations - leaves it too vulnerable to brute-force cracking. For my own understanding and for anyone else who stumbles across this question, is Rfc2898DeriveBytes still considered a secure method for hashing passwords? Along the same lines, is HMAC SHA256 with a salt but no iterations sufficient?

For the record, since I've been mandated to use anything other than Rfc2898DeriveBytes and since I know better than to roll my own from scratch, I intend to disassemble Rfc2898DeriveBytes and duplicate the code using SHA256 instead of SHA1.

  • The biggest weakness of Rfc2898DeriveBytes is that its implementation is slow, so you can only use a relatively low iteration count. Jul 8, 2015 at 19:34
  • @CodesInChaos That's not necessarily a weakness, a slower to generate hash can make brute force attacks and rainbow tables a lot less efficient, especially if you're using different salts for each password.
    – johnc
    Feb 26, 2017 at 23:50
  • 3
    @johnc My point is that the .net implementation is slow compared to a good implementation, widening the gap between the defenders performance and the attackers performance. Thus lowering security compared to a defender that uses a good implementation that allows them to choose a higher iteration count. Feb 26, 2017 at 23:53
  • 2
    The nuget package Microsoft.AspNetCore.Cryptography.KeyDerivation contains KeyDerivation.Pbkdf2 which implements exactly the same algorithm as Rfc2898DeriveBytes, but runs several times faster. It's usuable just fine outside of asp.net (core or otherwise). The api is also more convenient, and it adds support for HMAC-SHA-512 and HMAC-SHA-256, which let you additionally slightly decrease the advantage of a gpu cracker. May 11, 2017 at 13:00
  • Note that in later versions of this class you can specify a hash algorithm using specific constructors. Note that it is a bad idea to ask for more than the hash output of bytes from this class as it will repeat all iterations and may therefore give advantage to an adversary (besides slowing down your server more than you expect). Also note that SHA-512 is often faster than SHA-256 if implemented in software (note that Intel has created special opcodes for SHA-256, so speeds may vary). May 28, 2018 at 23:23

1 Answer 1


Rfc2898DeriveBytes implements the standard algorithm known as PBKDF2 and defined in RFC 2898 (hence the name). That algorithm uses a configurable underlying pseudorandom function, which is usually HMAC, and HMAC itself relies on a configurable underlying hash function, usually SHA-1. While all of this is configurable, a given implementation might not be as flexible, and, indeed, Rfc2898DeriveBytes always uses HMAC and always uses SHA-1 as underlying function for SHA-1.

Nowadays, the people collectively known as "auditors" tend to wail, whine, scream, mock and run in circles when they see anything that involves SHA-1. This is scientifically unwarranted. Right now, among all the published Science, there is not the slightest indication that SHA-1 when used in HMAC would be weak. Known weaknesses in SHA-1 are about collisions which do not impact HMAC (and these are still theoretical anyway). If some guy with a CISSP insists that SHA-1 actually makes PBKDF2 more vulnerable to brute-force, then that guy should go relearn his lessons.

Nevertheless, switching the SHA-256 is not a bad idea, so if shunning SHA-1 is what it takes to get rid of auditors, so be it.

However, the following must still be said:

  • Disassembling then modifying is a rather crude method and tends to lead to unmaintainable code. You could simply start from the actual source code (e.g. from here), or, even more simply (and with a cleaner legal status), reimplement it from scratch. .NET provides a HMAC/SHA-256 implementation; using it to do a PBKDF2 code is not hard.

  • Alternatively, you may try to reuse some other existing implementation, like this one.

  • You use PBKDF2 when you want to "hash a password", and not all functions are equal in that respect. A hashing function is any good only insofar as it is expensive for attackers to compute. In that respect, PBKDF2 with SHA-1 or SHA-256 is not the best choice; arguably, PBKDF2 with SHA-512 is a better deal (because existing GPU have a harder time optimizing SHA-512 than SHA-256), but other solutions may be preferable, in particular bcrypt. For more on this subject, read this, and more generally this.

    This means that while SHA-1 "weaknesses" do not make PBKDF2 weaker, it still is a function that can be very well optimized on GPU, which is, in that case, a problem -- but, and that's the important point here, SHA-256 fares no better.

  • In any case, by using a pure C# implementation, you accept that this specifically CPU-intensive will run with the inherent slowdown of that technology, which can be estimated to a factor of 2 to 3 when compared with optimized C code (or assembly). In other words, you give an advantage of 2x or 3x to attackers. Therefore, you might want to use some native code here, not pure C#.

  • 1
    "when used in HMAC" is a bit misleading in this context. With PBKDF2 the use of HMAC is useless at best (and costs a factor 2 with many implementations, including Rfc2898DeriveBytes). The reason why SHA-1 is fine in PBKDF2 is that collisions don't matter against password hashes. Jul 8, 2015 at 19:40
  • 1
    Thank you. What you said makes sense and fits with what I've found in my research. I think I'm pretty experienced - and have the arrogance to go with it - but when it comes to hashing/cryptography I'm never quite certain when I've crossed the line to idiocy. I definitely don't have the experience - or seniority - to call out the CISSP on his statements. I had found the existing implementation as well and will probably use it as a reference. Some of my concern with the question you pointed to was it's age and how things may have changed since then. Jul 8, 2015 at 19:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .