PasswordDeriveBytes vs Rfc2898DeriveBytes, Obsolete but way faster

tshao picture tshao · Aug 31, 2009 · Viewed 18.6k times · Source

I'm working on a encryption functionality based on classes inherited from SymmetricAlgorithm such as TripleDes, DES, etc.

Basically there're two options to generate consistent key and IV for my algorithm class, PasswordDeriveBytes and Rfc2898DeriveBytes, both inherit from DeriveBytes abstract class.

The PasswordDeriveBytes.GetBytes() method is marked as obsolete in .NET framework while Rfc2898DeriveBytes.GetBytes() is recommended, as it matches the PBKDF2 standard. However, based on my testing, calling the same GetBytes() method in Rfc2898DeriveBytes class is almost 15 times slower than that in PasswordDeriveBytes class, which leads to unexpected CPU usage (always higher than 50%).

Here're some testing data:

  • Iterations: 100
  • Algorithm type: DES
  • Original Text: "I'm a test key, encrypt me please"
  • Time:
    • PasswordDeriveBytes: 99ms
    • Rfc2898DeriveBytes: 1,373ms

Based on the testing, the bad performance of Rfc2898DeriveBytes is not acceptable in production environment.

Has anyone noticed this problem before? Any solution I can still use a standard one without hitting the performance? Any risk to use an obsolete method (could be removed in future version)?

Thanks guys!

Edit:

Probably I found where the problem is... The default iteration count number for PasswordDeriveBytes is 100, while for Rfc2898DeriveBytes is 1000. After I changed them to the same number as 1000, executing Rfc2898DeriveBytes is only double time.

Answer

BlackAura picture BlackAura · Aug 31, 2009

They aren't the same thing.

Rfc2898DeriveBytes is an implementation of PBKDF2. PasswordDeriveBytes is an implementation of PBKDF1. PBKDF2 generates a different output, using a different method, and a much larger number of rounds than PBKDF1.

Password hashing functions, such as these, which are used for key derivation are supposed to be slow. That's the point - it makes them much more difficult to crack.

The two functions are not compatible, and PasswordDeriveBytes is not nearly as secure.