I am a bit of a newbie around Security nitty gritties and especially around Cryptography.
In the application we are building(ASP.net application built on .NET 3.5), we are currently using Databases to save our users authentication information (AD etc is not an option at this point). The intention is to do a one way salted hash of the passwords using SHA256Managed on user creation and then validate the users using the same. Ideally, we do not want to use any third party dll's for the hashing algorithm unless absolutely necessary to avoid any unnecessary dependencies.
Quest开发者_开发知识库ions:- 1. Is there a better option than doing a salted one way hash? 2. Is SHA256 a reasonably reliable / secure option or should we be considering anything else? 3. Is the SHA256Managed implementation in System.Cryptography good enough in terms of it speed etc or should we be considering 3rd party alternatives to it?
Any pointers as to the approach / implementation will be helpful.
I did some research on this back in the day, and the consensus was BCrypt was one of the best ways to do a one way hash.
You can see a C# implementation here: http://derekslager.com/blog/posts/2007/10/bcrypt-dotnet-strong-password-hashing-for-dotnet-and-mono.ashx
In addition, what's nice about BCrypt is you can decide how many rounds you'd like it to go through.
So, you can make it take about 1 second to encrypt for example. For a user, that's an acceptable wait time, but for someone trying to attack you through brute force, 1 second is an eternity.
I am no security expert, so take what I say here as a grain of salt. A salt you can send in to your BCrypt method :)
In addition, here's some advice from Atwood on this: http://www.codinghorror.com/blog/2007/09/youre-probably-storing-passwords-incorrectly.html
Update:
Since answering this, NuGet has made using BCrypt much easier: http://nuget.org/packages?q=bcrypt
I can't vouch for any particular implementation there, so take a look at the code, but this should make using and integrating BCrypt much easier.
- Yes, retina scan (just kidding). Storing passwords as hashes with salt is the correct way.
- SHA256 is good. Obviously I don't know the type of an application you are working on, but SHA256 is good for the vast majority of projects. You can always go to a higher key length (384, 512) if required. Consult with your security architect.
- SHA256Managed (we are talking .net, right?) is good. We use it in our projects.
Please also consider reading this: http://www.obviex.com/samples/hash.aspx
Yes, there's nothing wrong with SHA256 and certainly SHA256Managed will be "fast enough" for most use cases (I'm sure you're not expecting to be validating 1000s of login requests per second, and even if you were, the rest of the site would still be dwarfing the login requests...)
But have you considered the Membership stuff that's built-in to the framework? They're already done all the hard work in terms of securely storing credentials, and implementing all the support functionality as well (such as password resets, etc)
Storing password hashes with salt it correct. However, it's easy to get even that much wrong. Sure, right now SHA256 will keep the baddies at bay, but give it a few years. Suddenly, SHA256 might not seem so secure anymore. You need to use BCrypt, a future-proof hashing algorithm.
Problem with doing just one pass of SHA256 is it is too fast and one with great hardware can generate rainbow tables for lots of salts easily...to get around this you need to perform key stretching....kI'm not going to give you a lesson on key stretching but the bcrypt implementation that people talk about performs key stretching. If you want a more modern alternative to bcrypt which uses HMACSHA256 or 512 in .NET, I recomend this API:
https://sourceforge.net/projects/pwdtknet/
精彩评论