Best way to store password in database

374,857

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):

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)

Solution 3

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

Solution 4

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

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

Solution 5

I'd thoroughly recommend reading the articles Enough With The Rainbow Tables: What You Need To Know About Secure Password Schemes [dead link, copy at the Internet Archive] and How To Safely Store A Password.

Lots of coders, myself included, think they understand security and hashing. Sadly most of us just don't.

Share:
374,857
Crash893
Author by

Crash893

nonya

Updated on July 08, 2022

Comments

  • Crash893
    Crash893 almost 2 years

    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

  • Mitch Wheat
    Mitch Wheat almost 15 years
    @Paolo Bergantino: "storing the password in the database is the proper thing to do" - I would disagree with that statement.
  • Paolo Bergantino
    Paolo Bergantino almost 15 years
    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.
  • Mitch Wheat
    Mitch Wheat almost 15 years
    @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.
  • Paolo Bergantino
    Paolo Bergantino almost 15 years
    Not only is that what I said, I directed him to a plethora of posts that discuss salts and such further...
  • Mitch Wheat
    Mitch Wheat almost 15 years
    @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
  • Paolo Bergantino
    Paolo Bergantino almost 15 years
    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.
  • Vahid
    Vahid almost 15 years
    Wayne, by salting before computing the hash, the rainbow table is effectively defeated, provided the salt is of sufficient size.
  • zebrabox
    zebrabox almost 15 years
    I wouldn't use MD5 for hashing - it's basically broken mscs.dal.ca/~selinger/md5collision
  • joej
    joej almost 15 years
    Thanks Paolo -- you are correct. As the use of SHA2 is as easy as using MD5 & SHA1, please use the stronger hash algorithm.
  • Robert Rossney
    Robert Rossney almost 15 years
    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.
  • Paolo Bergantino
    Paolo Bergantino almost 15 years
    @Robert: That's getting dangerously close to a petty semantics game, but I'll fix it nonetheless...
  • waiwai933
    waiwai933 almost 15 years
    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.
  • Crash893
    Crash893 almost 15 years
    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.
  • mistertodd
    mistertodd about 14 years
    @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.
  • mistertodd
    mistertodd about 14 years
    SHA-1 hasn't been broken. But to paraphase Bruce Schneier: Walk, don't run, to SHA-2.
  • zebrabox
    zebrabox almost 13 years
    @Johan Looks like the link is now broken which is a shame. Here's an alternative codahale.com/how-to-safely-store-a-password
  • mjuarez
    mjuarez about 11 years
    Well, wouldn't that be broken too then? You just enter the other password that generates the same hash, and you're in. You don't need to know the original password. The way to fix this is if you salt the password before hashing.
  • WiiMaxx
    WiiMaxx over 10 years
    @mjuarez if you add a salt to the password befor you use MD5 the collision doesn't matter because you can't use the other password
  • trusktr
    trusktr over 10 years
    "So, you should 'salt' your passwords"... But the salt is usually stored in the database along with the password, so how does that help? Te attacker simply has to add the salt to the dictionary attack phrases he is testing against. How is that more secure other than it won't reveal duplicate passwords?
  • Dynom
    Dynom almost 10 years
    In my opinion, you should always use slow algorithms (like Blowfish, for example) to store passwords. This writeup is a much better answer: security.stackexchange.com/questions/211/…. Just putting it here, because this page still appears high in the search results.
  • mlissner
    mlissner almost 9 years
    Following this advice for password storage would be doing it woefully wrong.
  • Francisco Zarabozo
    Francisco Zarabozo over 8 years
    @joej "You never ... really ... need to know the user's password" - that's a very short sighted assumption. There are many kind of applications where having a password stored in a way that can be retrieved is genuinely necessary. For example, an application that needs to frequently login to another system with stored credentials, supplied and updated by a user.
  • thinkOfaNumber
    thinkOfaNumber almost 8 years
    @FranciscoZarabozo that's bad design of the both systems, because when my system is compromised, now my users on your system are too. oAuth and the like get around this, but you need the "other system" to support it. You should never reversibly encrypt a users password.
  • Francisco Zarabozo
    Francisco Zarabozo almost 8 years
    @thinkOfaNumber Again saying "you should never"... Tell me, how would you store the credentials to access an API like a REST API for PayPal or Twilio or any other system that provides you with a user and key (that acts as a password)? What if your system interfaces with those APIs not only for you but for several clients? You NEED to find a way to secure such data and that way exists. Two way encryption methods serve a purpose, they are not there as a "bad choice". Bad choices come from how you decide to implement it.
  • thinkOfaNumber
    thinkOfaNumber almost 8 years
    @FranciscoZarabozo PayPal uses OAuth 2.0 as the auth mechanism. If PayPal allowed you to store my PayPal pwd in a 3rd party app, it would be a disaster, as they have little control over every unrelated app's security. An OAuth token gets around this, and is not the password, so it's ok to store in a reversibly encrypted form. Nor is my PayPal pwd ever made available to the third-party system, as when I log into PayPal I'm on their website, not the third parties. That's how your system should interface with them. This discussion might warrant it's own question to ask if it's "ever OK"!
  • WoJ
    WoJ over 7 years
    @thinkOfaNumber: you should have a look at POP and IMAP and come back with the right way to authenticate on these services. Also ping Google about that as they are storing these credentials in gmail (when you need to access mail systems via IMAP or POP). Seriously - saying this just shows that you have not worked about real life APIs.
  • thinkOfaNumber
    thinkOfaNumber over 7 years
    @WoJ Let's keep this technical and leave the guesses about my personal history for the pub. I admit that webmail is one case I never thought of, but POP and IMAP date back to the 80's when security was a different thing. Just because you can do it doesn't mean you should do it however, and I used to forward my POP mail to gMail so that I could avoid this very situation. PayPal would block your system from accessing them if you did the same, for good reason. A modern API developer should ensure that storing passwords is not necessary (or possible) by providing oAuth and other mechanisms.
  • chilladx
    chilladx almost 7 years
    owasp.org/index.php/Password_Storage_Cheat_Sheet is a good reference on hashing/salting.