First, some terms that are important:
Hashing - The act of taking a string and producing a sequence of characters that cannot be reverted to the original string.
Symmetric Encryption - (Usually just referred to as 'encryption') - The act of taking a string and producing a sequence of characters that can be decrypted to the original string through the use of the same encryption key that encrypted it.
Rainbow Table - a lookup table that contains all variations of characters hashed in a specific hashing algorithm.
Salt - a known random string appended to the original string before it is hashed.
For the .NET Framework, Bcrypt does not yet have a verified reference implementation. This is important because there's no way to know if there are serious flaws in an existing implementation. You can get an implementation of BCrypt for .NET here. I don't know enough about cryptography to say whether it's a good or bad implementation. Cryptography is a very deep field. Do not attempt to build your own encryption algorithm. Seriously.
If you are going to implement your own password security (sigh), then you need to do several things:
- Use a relatively secure hash algorithm.
- Salt each password before it's hashed.
- Use a unique and long salt for each password, and store the salt with the password.
- Require strong passwords.
Unfortunately, even if you do all this, a determined hacker still could potentially figure out the passwords, it would just take him a really long time. That's your chief enemy: Time.
The bcrypt algorithm works because it takes five orders of magnitude longer to hash a password than MD5; (and still much longer than AES or SHA-512). It forces the hacker to spend a lot more time to create a rainbow table to lookup your passwords, making it far less likely that your passwords will be in jeopardy of being hacked.
If you're salting and hashing your passwords, and each salt is different, then a potential hacker would have to create a rainbow table for each variation of salt, just to have a rainbow table for one salted+hashed password. That means if you have 1 million users, a hacker has to generate 1 million rainbow tables. If you're using the same salt for every user, then the hacker only has to generate 1 rainbow table to successfully hack your system.
If you're not salting your passwords, then all an attacker has to do is to pull up an existing Rainbow table for every implementation out there (AES, SHA-512, MD5) and just see if one matches the hash. This has already been done, an attacker does not need to calculate these Rainbow tables themselves.
Even with all this, you've got to be using good security practices. If they can successfully use another attack vector (XSS, SQL Injection, CSRF, et. al.) on your site, good password security doesn't matter. That sounds like a controversial statement, but think about it: If I can get all your user information through a SQL injection attack, or I can get your users to give me their cookies through XSS, then it doesn't matter how good your password security is.
Other resources:
- Jeff Atwood: .NET Encryption Simplified (great for an overview of hashing)
- Jeff Atwood: I just logged in as you
- Jeff Atwood: You're probably storing passwords incorrectly
- Jeff Atwood: Speed Hashing
Note: Please recommend other good resources. I've must have read a dozen articles by dozens of authors, but few write as plainly on the subject as Jeff does. Please edit in articles as you find them.