views:

996

answers:

4

Ok, I have an application written in C#. We have data in an SQL Server. Among that data we have user accounts, which will give access to the application.

I've read around, and I know that you should salt and hash and possibly hash a bunch of times, etc. But, where do I do what? What do I send to and from the SQL Server? Exactly what do I store in the database? Do I hash it in SQL? (possibly a hash function there, like in mysql?) Do I hash and do the fancy stuff in my code? Do I send the hash to the server and compare, or do I get the hash from the server and compare in my application? What about the salt? Where do I make it? Where do I store it? How do I get it?

In other words, could someone give me a nice and clear walkthrough of a login scenario (and possibly a user add/reset password scenario). What goes where, what should be used where, etc.

Hope someone can clear these things up for me =)

+6  A: 

For C# + SQL Server, you can just use the MembershipProvider model, which will take care of all this for you.

And IMO, the most important part of getting all this stuff right is not doing it yourself. Rather, rely on the mechanism provided by your platform. It's just so easy to get it wrong in a subtle way that appears to work. Then you deploy, and you don't even know anything is wrong until after you are hacked.

Joel Coehoorn
Built in mechanisms can appear to work just as easily as a home grown implementation. The difference is after you've been hacked you have no idea if you just set it up wrong or there's some exploit you're unaware of.
Spencer Ruport
@Spencer: That is about the most ridiculous thing I have heard in a long time.
Geoffrey Chetwood
But I'd argue that, with a built-in mechanism, there's a significantly smaller risk that you'll be hacked, because the teams at Microsoft is more careful about security and safe programming than the average developer. A flaw in their provider, while possible, is less likely than flaw in yours...
rwmnau
I have too gotten the... not do it yourself stuff... but since I am making the application, I have to do _something_ myself! If not I would just tell our customers to use another application and go find another job :p
Svish
And by that I don't mean I do this stuff just to do it, but because it is a needed part of the application we are making... and no matter how you do it, or what you use, some way or another, it have to be merged into your application so that it can use it :)
Svish
@Svish: I don't think you understand. You need to read about how the membership provider works. Joel is 100% correct here and if you roll your own you are going in the wrong direction.
Geoffrey Chetwood
@Svish: Here, this is a good place for you to start: http://devpinoy.org/blogs/comgen/archive/2007/08/15/use-membership-api-in-winforms.aspx
Geoffrey Chetwood
I'm not saying "Don't do it". I'm saying "Steal someone else's implementation" At least then if things go wrong you'll have somewhere to point the finger (you can pick which finger) ;)
Joel Coehoorn
Well, it's just that when you steal someone else's code, you still sit with the responsibility if it turns out that that someone was a crook and made bad code :p I see your point though. Will take a look at that membership stuff, but we'll see what I end up doing...
Svish
@Svish: If you are asking this question, then you should *definitely* trust Microsoft's code over your own.
Geoffrey Chetwood
A: 

If you are using ASP.NET, using the built in membership stuff is a cakewalk to implement I would recommend going that way.

However, as a general question, I would implement the hashing in your local code, then only send the hash values out to the database. For salts there is a number of ways to do it, you can create a random salt, or you can salt the value using the records id, or something else. Again, I would do it in the C# code. There is a helpful method in the framework for doing it.

Mitchel Sellers
Not using ASP.NET. It's a C# regular WinForms application.
Svish
+1  A: 

I agree with Joel Coehoorn completely, the best choice is to trust someone else's tried and true implementation. If, however, you're determined to roll your own security implementation, then my advice is the following:

  1. Store the hash and salt in the database.
  2. Generate the hash and the salt in your own code. That way you're not tying yourself to a specific database.
  3. Never send the password over the wire as plaintext. I would recommend fetching the hash and the salt from the database and comparing it to the ones you calculated from the username and password supplied by the party that wishes to be authenticated.
Vojislav Stojkovic
Thank you! Clear and right to the point :) Appreciate it!
Svish
A: 

I did this myself a number of years ago before the Membership Provider model was available.

We used the functions built-into ASP.NET to handle the hashing of the password; it's the static method HashPasswordForStoringInConfigFile in the FormsAuthentication namespace. You give it a password and an encryption choice and it returns the hashed password.

Our flow was: - Get the hashed password from the database for hte entered user name. - Hash the entered password. - Do they match? If so, continue, else logon failed.

When changing the password, we sent the hash to the database for storing; we did not send the unencrypted password.

And, I believe, it is what the MembershipProvider is doing under the covers today.

To reiterate too, the most important piece when doing forms authentication regardless of how you are doing it, is to work over a secure (HTTPS) connection.

Jeff Siver
You should be able to replace this entire answer with "Use the membership provider".
Geoffrey Chetwood