Is PBKDF2-based System.Cryptology.RFC2898DeriveBytes() "better" for Unicode Password hashing than traditional methods?

PasswordDeriveBytes implements the PBKDF1 key-derivation function. A KDF is a function which transform a piece of secret data (here, a "password", i.e. the kind of data which fits in a human brain and can be typed with human fingers) into a sequence of bits adequate for algorithms which need a symmetric key (e.g. symmetric encryption). A KDF is not meant for anything else, in particular password storage.

A hash function can be used as a KDF, provided that the symmetric key you need is no longer than the hash function output size. However, such a KDF would be very crude. One feature which good KDF should provide is to be adequately slow. This is because "passwords" are, by nature, vulnerable to exhaustive search (also known as "dictionary attack": users tend to choose as passwords rather simple words or combinations which can be guessed with only a few millions or billions tries). In a given system, one can usually tolerate a relatively slow KDF: a user trying to authenticate will not see the difference between a 1µs and a 1ms delay for the key-derivation function; but a 1000x slowdown is deadly for the attacker: it converts a one-day breaking effort into a three-years breaking effort.

PBKDF1 includes an "iteration count" which is a parameter meant exactly for that: to make the key derivation adequately slow, in a configurable way. A simple hash function is just too fast for that. Usage as a KDF is precisely where you would prefer PBKDF1 over a hash function. Actually, PBKDF1 is not recommended; PBKDF2, from the same standard, is supposed to be more robust.

Hash functions are much more generic objects than KDF, and have many other usages, which KDF do not fulfill.

What you want to do is unclear: you use the term "signature", which normally means "asymmetric digital signature" as with RSA or ECDSA; there are some people who tend to use the term "signature" to designate a symmetric integrity check, such as a MAC (calling it a "signature" is improper, but widespread). However, this entails some piece of secret at some point, a key, and a hash function is key-less.


The NIST approves of PBKDF2 when hashing and storing passwords, however that is not its original intended purpose. Notably, StackExchange also uses PBKDF2 for the same purpose. Source code is available here.

See this answer for a comparison between BCrypt and PBKDF2. BCrypt is the the more conventional method of storing passwords.

I'm considering PBKDF2 since it's built into .NET and is already FIPS compliant.


Unless I've missed something, PasswordDeriveBytes - and other PBKDF implementations - are not intended for storing passwords, nor are they to be used instead of a "typical" hash.

What it is intended for, is to create an encryption key, for symmetric encryption, based on a user-provided password.

To clarify, consider the following situation:
You have an application, that requires encrypting a file. This is done at the user's discretion, and can be decrypted at his choice.
Oh, let's say MS Word has a feature to encrypt it's contents. Or an encrypted ZIP file.
You want to give the user the control to access it, but don't want to rely on the user to generate a strong, random, exactly-256-bits-key, which would make it difficult to remember, etc.
So, you allow the user to set any password he wants - and derive the encryption key from that.

At no point are you storing the password, or using a simple hash to store it. It is only intended for creating key material.