views:

3001

answers:

10

I am working on a project that has to have authentication (user name/pass)

It also connects to a database so i figured i would store the user name and password there but it seems like not such a good idea to have passwords as just a text field in a table sitting on the db

I'm using C# and connecting to a 2008 express server. can anyone suggest ( with as many examples as possible) what is the best way to store this type of data?

(i am open to the idea that this info not be stored in the db if a good reason can be provided)

+1  A: 

Store your passwords as encryted text.

.NET Encryption is pretty easy.

David Basarab
But then were do you store the key?
mfloryan
The key you can derive from an algorithm or have it in your code.
David Basarab
+2  A: 

I would MD5/SHA1 the password if you don't need to be able to reverse the hash. When users login, you can just encrypt the password given and compare it to the hash. Hash collisions are nearly impossible in this case, unless someone gains access to the database and sees a hash they already have a collision for.

waiwai933
I wouldn't use MD5 for hashing - it's basically broken http://www.mscs.dal.ca/~selinger/md5collision/
zebrabox
Actually, it's not that broken. What they can do is find the same hash value for two different files. What they can't do is reverse the MD5 and get a working password.
waiwai933
+1  A: 

In your scenario, you can have a look at asp.net membership, it is good practice to store user's password as hashed string in the database. you can authenticate the user by comparing the hashed incoming password with the one stored in the database.

Everything has been built for this purposes, check out asp.net membership

codemeit
+37  A: 

You are correct that storing the password in a plain-text field is a horrible idea. However, as far as location goes, for most of the cases you're going to encounter (and I honestly can't think of any counter-examples) storing the representation of a password in the database is the proper thing to do. By representation I mean that you want to hash the password using a salt (which should be different for every user) and a secure 1-way algorithm and store that, throwing away the original password. Then, when you want to verify a password, you encrypt the value and compare it to the encrypted value in the database.

So, while it is a good thing you are thinking about this and it is a good question, this is actually a duplicate of these questions (at least):

To clarify a bit further on the salting bit, the danger with simply encrypting a password and storing that is that if a trespasser gets a hold of your database, they can still use what are known as rainbow tables to be able to "decrypt" the password (at least those that show up in the rainbow table). To get around this, developers add a salt to passwords which, when properly done, makes rainbow attacks simply infeasible to do. Do note that a common misconception is to simply add the same unique and long string to all passwords; while this is not horrible, it is best to add unique salts to every password. Read this for more.

Paolo Bergantino
@Paolo Bergantino: "storing the password in the database is the proper thing to do" - I would disagree with that statement.
Mitch Wheat
I meant storing the password in the database as opposed to storing it elsewhere. Taking that sentence out of context makes it seem like I am supporting storing plain passwords, if you read the rest I obviously don't.
Paolo Bergantino
@Paolo Bergantino: I understood what you meant perfectly. And I did not take it out of context. Best practice is not to store even the ecnrypted password, but to store a salted hash of the encrypted password.
Mitch Wheat
Not only is that what I said, I directed him to a plethora of posts that discuss salts and such further...
Paolo Bergantino
@Paolo Bergantino: you sure there is not a typo in your post? It says "For most of the cases you are going to encounter (and I honestly can't think of any counter-examples) storing the password in the database is the proper thing to do." ??? It seems to contrdict your comments
Mitch Wheat
That comment is only directly addressing his concern of whether a database is the proper place to store the password/salt/hash/whatever you want to call it. I am saying a database IS the proper place to store it, BUT with the caveat you have to salt it and encrypt it.
Paolo Bergantino
Don't worry Paolo, what you said makes sense.
SP
What Paolo said directly contradicts itself. A salted hash of a password is not a password. Storing a salted hash of the password in the database is not storing the password in the database. The body of the answer is perfectly appropriate, but its first sentence is extremely misleading.
Robert Rossney
@Robert: That's getting dangerously close to a petty semantics game, but I'll fix it nonetheless...
Paolo Bergantino
+9  A: 

As a key-hardened salted hash, using a secure algorithm such as sha-512.

nilamo
Wow, #3 by votes, and no comments. I was expecting someone to say something like "you should have mentioned a _random_ salt with some decent length to it."
nilamo
+7  A: 

The best security practice is not to store the password at all (not even encrypted), but to store the salted hash of the encrypted password.

That way it is (practically) impossible to retrieve a plaintext password.

Mitch Wheat
Not so. If the value is exposed, a brute-force attack can be performed ala Rainbow Tables. http://en.wikipedia.org/wiki/Rainbow_table
Wayne Hartman
Wayne, by salting before computing the hash, the rainbow table is effectively defeated, provided the salt is of sufficient size.
Mike Rosenblum
@Wayne Hartman: Not so. If the salt value is exposed, then you must generate a new rainbow table for that specific salt value. The point of a rainbow table is to have hash values calculated beforehand. And nobody will have a rainbow table for his specific salt.
Ian Boyd
+6  A: 

Background You never ... really ... need to know the user's password. You just want to verify an incoming user knows the password for an account.

Hash It: Store user passwords hashed (one-way encryption) -- via MD5, or strong hash like SHA1. A search for "c# encrypt passwords" gives a load of examples.

See the online SHA1 hash creator for an idea of what a hash function produces.

Now, a hashed passwords means that you (and database thieves) shouldn't be able to reverse that hash back into the original password.

How to use it: But, you say, how do I use this mashed up password stored in the database?

When the user logs in, they'll hand you the username and the password (in its original text) You just use the same hash code to hash that typed-in password to get the MD5 or SHA1 (etc) version.

So, compare the two hashed passwords (database hash for username and the typed-in & hashed password). You can tell if "what they typed in" matched "what the original user entered for their password" by comparing their hashes.

Extra credit:

Question: If I had your database, then couldn't I just take a cracker like John the Ripper and start making hashes until I find matches to your stored, hashed passwords? (since users pick short, dictionary words anyway ... it should be easy)

Answer: Yes ... yes they can.

So, you should 'salt' your passwords. See http://en.wikipedia.org/wiki/Salt_(cryptography)

See "How to hash data with salt" C# example --> http://www.obviex.com/samples/hash.aspx

joej
Nice post, except for one thing: md5 and sha1 have both been broken. You should probably go with a stronger algorithm, such as maybe the SHA2 family.
Paolo Bergantino
joej
SHA-1 hasn't been broken. But to paraphase Bruce Schneier: Walk, don't run, to SHA-2.
Ian Boyd
+1  A: 

I may be slightly off-topic as you did mention the need for a username and password, and my understanding of the issue is admitedly not the best but is OpenID something worth considering?

If you use OpenID then you don't end up storing any credentials at all if I understand the technology correctly and users can use credentials that they already have, avoiding the need to create a new identity that is specific to your application.

It may not be suitable if the application in question is purely for internal use though

RPX provides a nice easy way to intergrate OpenID support into an application.

Crippledsmurf
I agree that openID rocks peoples faces off but for this application it is a in house database for a company I doubt they would like any old person coming in to log on. also web access is not needed for this app to work correctly so i would hate to require it.
Crash893
+1  A: 

I'd thoroughly recommend reading this article.
Lots of coders, myself included, think they understand security and hashing.
Sadly most of us just don't.

zebrabox
+1  A: 

Whatever you do, if you go with encryption, don't store the key in the code as a previous poster mentioned. That's just poor practice.

Woody