Does anyone have a reference implementation (ideally 3rd party certified, or government approved) way one-way hash a password for C# and or Java?

Ideally,I'd like to see something that includes a "salt and pepper" technique as mentioned here as well as any other modern security technique for validation that might be applicable.

The content I want to protect is information the user can remember, such as a password, or the answer to a challenge question.

If you don't have a complete code sample, a general description of which algorithm you would choose, and example methods of salting and peppering would be helpful.

  • The term "password storage" is wrong for what you seem to be looking for. You want to store something that lets you verify that the user can produce the right password or secret. But it is not enough to produce the password itself for use elsewhere (which is a good thing). Assuming that is true, can you fix it here and other places you've used it? – nealmcb Feb 13 '11 at 1:38
  • @nealmcb - Done, let me know of other spots that are not worded right and I'll clarify the language. – AccidentallyObtuse Feb 13 '11 at 3:07
  • In your edit, do you mean to say "US government approved"? – nealmcb Feb 16 '11 at 20:24
  • @nealmcb FIPS is just an example of an approval and verification. It would be nice to see what other approvals exists, and draw a consensus if any. – AccidentallyObtuse Feb 16 '11 at 21:58
  • Although I have accepted an answer I'm still interested in other trusted methods to store and encrypt a password, and any corresponding validation that may exist. – AccidentallyObtuse Feb 16 '11 at 22:03
up vote 4 down vote accepted

Given your new "government approved" requirement, my guess is that one good solution would be PBKDF2 from RFC 2898. It is implemented for .NET in Rfc2898DeriveBytes Class (System.Security.Cryptography). You presumably want to substitute SHA-256 for SHA-1 in there.

I also just ran across the Fairly Secure Hashed Password: fshp which is like PBKDF1 but with SHA-256 by default. It supports a variable number of iterations, defaulting to 4096. It uses 64 bit salts. They have implementations there for .NET, Python, Ruby, Perl, PHP5, Java and JavaScript.

As described and discussed at .net impl of bcrypt - Stack Overflow, it seems that for .NET/CLR another good option (though not NIST-approved) is

and for Java a good option is

I guess neither seems to have the "pepper" concept, or the space complexity of scrypt.

  • Thanks for adding the PBKDF2 class. I wasn't clear that it existed in .NET or that this RFC-Named class was newer/better than PasswordDeriveBytes. Thanks a ton! – AccidentallyObtuse Feb 16 '11 at 22:02

The basics

The basic approach is Hash(secret | salt), which is stored along with the salt. Obviously it's important to use a modern hash algorithm like one of the SHA2 variants (though currently SHA1 is not totally broken like MD5 is). Note that if you are storing challenge questions this way, you probably want to Trim() and ToLower() the secret before hashing it. This may reduce the complexity somewhat, but security questions aren't intended to have high entropy like a password anyway.

What about brute-force attacks like Rainbow tables?

Concerns about brute-force attacks can be mitigated in two ways:

  1. Require a minimum amount of entropy in the secret (length, complexity, etc.).
  2. Increase the amount of computation required to perform the hash.

The method used in bcrypt is a good improvement on standard hashing because it increases the amount of time to calculate the hash by many orders of magnitude. Basically, it just iteratively hashes the secret many times: Hash(Hash(...Hash(secret | salt)...))

Because the amount of time is still relatively small (hundreds of milliseconds), it does not add an intolerable delay to the legitimate user. But it can ruin automated brute-force attacks.

That's not good enough

If the additional difficulty of bcrypt is insufficient, try scrypt. It works like bcrypt but needs to save each iterative hash in memory for a final merge at the end. This adds the same time complexity as bcrypt but also increases space complexity, making it more difficult to implement in hardware, especially in parallel.


Honestly, I'm not aware of a C# library to implement this, let alone one "certified" by some official body, but it wouldn't be too difficult. Assuming you write thread-safe code, and the password verification takes place on a trusted system like a server, implementation concerns like side-channel attacks are minimized.

Further reading: This answer to Is BCrypt a good encryption algorithm to use in C#? Where can I find it?

  • Thanks! I heard somewhere that ToUpperInvariant() is more reliable in cross-culture comparisons of strings instead of ToLower(). What do you think? – AccidentallyObtuse Feb 12 '11 at 20:39
  • Any case elimination function will work in the general case. I'll be the first to admit that I'm no expert in i18n, so I'd love to hear more about why ToUpperUnvariant() is better. In this case it probably doesn't matter much, because you're comparing two strings typed by the same person. Presumably, they typed it the same way both times. – Justin Morgan Feb 12 '11 at 22:08
  • 1
  • 1
    Just something worth noting. I often see references to md5 being totally broken. It has collisions. This is not the same thing as being totally borked. While I would use sha1 or better given the opportunity, I would like to see an md5 collision that allows malware in an iso for example. Just thoughts. – RobotHumans Feb 13 '11 at 20:04
  • 1
    To my knowledge, FIPS has not approved any method for password storage. FIPS 800-3 defines secure hashing, but basically just says "use SHA1 or SHA2". As far as the government is concerned, bcrypt and scrypt are just academic. – Justin Morgan Feb 17 '11 at 3:12

Your Answer


By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.