Best way to store password in database [closed]
I am working on a project that has to have authentication (username and password)
It also connects to a database, so I figured I would store the username and password there. However, it seems like not such a good idea to have passwords as just a text field in a table sitting on the database.
I'm using C# and connecting to a 2008 express server. Can anyone suggest (with as many examples as possible) what the best way to store this type of data would be?
P.S I am open to the idea that this info not be stored in the database if a good reason can be provided
Solution 1:
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 hash the value (using the same hashing algorithm and salt) and compare it to the hashed 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):
- How to best store user information and user login and password
- Best practices for storing database passwords
- Salting Your Password: Best Practices?
- Is it ever ok to store password in plain text in a php variable or php constant?
To clarify a bit further on the salting bit, the danger with simply hashing 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.
Solution 2:
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 a strong hash function. 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 (But don't use SHA1 as a hash function, use something stronger such as SHA256).
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 stored 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 the Wikipedia article on salt
See "How to hash data with salt" C# example (archived)