Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have a web service. Right now, I have passwords stored in plain text in a MySQL table on my server. I know this isn't the best practice, and that is why I am working on it.

Why should passwords be encrypted if they are being stored in a secure database? I realize that if someone hacks in to my database they will get everyone's password. But I have other problems if someone gets in my database, for example, deleting data.

The scenario I can think of is that you are hacked. You restore a database from a couple of hours ago and everything is well. However, if your passwords are plaintext... The thief has all the passwords and you have to reset them all. Hassle to your users.

If the passwords were encrypted, you could just restore to previous database. Is this correct thinking?

share|improve this question
117  
I would go one step further. It's not enough to encrypt it. You'd want to hash it. That way, not even you should be able to know what your users' plaintext passwords are. –  Santa Jan 30 at 0:36
63  
@Santa Hashing the password is not enough. You have to add some salt to make the recipe good enough... –  Bakuriu Jan 30 at 10:15
14  
Please please have a look at this relevant Security.StackExchange post: How to securely hash passwords? –  Adnan Jan 30 at 12:10
9  
Disgrunted DBA says... select * from user, and then sells that list for severence pay. Nothing is ever secure. –  Jon Raynor Jan 30 at 19:50
    
add comment

15 Answers

First up, you should be more free with read-only access rights than read-write. It might be possible that a hacker has access to your data but isn't able to edit it.

But, much more importantly, this is not about you. The fact that you might be screwed if someone has full access to your database is irrelevant. Much more important is your user's data.

If you recover your database, the hacker still has access to your user's account.

And who knows what else? What if they use the same password at Google? Or PayPal? What if that gives a hacker access to their mother's maiden name, or the last 4 digits of their credit card?

What if that gets them into other accounts? Don't put it past a hacker to go through a user support system and get more info.

Just ... just don't. That's your user's private information and you don't need to be able to see it. It's also your reputation. Encrypt it.

EDIT: One extra comment, to save any future reader from reading every answer and comment ...

If you're going to encrypt (in the strictest sense) then you need to use a public / private key pair, which is fine but makes life a little bit more difficult for both you and your user.

A simpler, and just as effective, solution is to random-salt and hash the password. Hashing alone is not enough; if your user uses a common password, it will appear in reverse-hashing tables, which are readily available with a simple internet search.

share|improve this answer
88  
Or better, hash it! –  Blorgbeard Jan 30 at 0:31
29  
This. "I have other problems if someone gets in my database". It's your database, you expect to have problems if it gets hacked. But by storing plaintext passwords you give all your users problems with, potentially, all their other accounts. How many people do you think really use a different password on every single website? –  Carson63000 Jan 30 at 0:33
13  
Please follow Blorgbeard's advice, maybe read this‌​. Encrypting passwords does not provide protection when your web server has been compromised. The key to decrypt the passwords must be stored somewhere on the server. Hashing the passwords means that even in the event that someone has full access to the machine, they cannot recover the passwords easily. –  Slicedpan Jan 30 at 10:16
7  
Why would you ever need to encrypt passwords if it provides no value to your system? At what point in time will you have to decrypt passwords, other than for comparison? @pdr, you shouldn't be telling the OP to encrypt, you should be telling him to salt and hash. –  NobleUplift Jan 30 at 16:09
3  
You also want to hash the answers to their password recovery questions. Otherwise those can be used to get into other sites also, just like passwords. –  Zan Lynx Jan 30 at 20:35
show 14 more comments

If you get hacked you can restore the site from backups and fix it. But the hacker still has passwords for everyone's accounts! There are documented real world examples of this happening (Sony, Linked-in), where if the password tables had been properly hashed and salted, securing and restoring the sevice quickly would have been much easier.

It's probably a good idea to assume you will be hacked, and design your backup strategy and encrypt any sensitive data with this assumption in mind. And it's not just hackers you need to protect against. Disgruntled, dishonest, or just clueless employees could give away plain-text passwords.

Without hashing you will have to disable access for everyone until they change their password (which, even if possible, will be a huge headache for everyone). If the passwords had been hashed and salted you could restore the web service and it would be much harder for an attacker to gain access to people's accounts.

A properly hashed and salted password is basically one-way. You can't easily guess the password from the hashed password. Even you, as the service provider won't be able to guess it, you can only reset it.

Also, as Elin said, don't try and roll your own hashing (or encryption). Use a standard library.

share|improve this answer
2  
12  
+1 for mentioning disgruntled employees. It's easy to overlook when you're a one-man shop or a small company, but eventually you'll have people working with the data that you haven't personally vetted. –  Jon of All Trades Jan 30 at 5:43
2  
Writing the foreach to loop through a list of users and then hash their passwords is the work of a few minutes and frankly 4000 is hardly anything. php.net/manual/en/function.hash.php –  Elin Jan 30 at 13:21
3  
You keep switching between the terms "encrypt" with "hash and salt" @david25272. Don't confuse the two, which are entirely different. Now the OP is looking for an encryption algorithm, and not a hash algorithm. Also, it's "salt and hash", not "hash and salt". You can't salt after you hash. –  NobleUplift Jan 30 at 16:16
1  
Also @phpmysqlguy, read my answer for suggestions on salting and hash algorithms. –  NobleUplift Jan 30 at 16:20
show 4 more comments

But I have other problems if someone gets in my database, i.e. deleting data.

It's not about the problems you have, it's about the problems it might cause for all your other users. It's about removing temptation (or even worse, potential liability) for people working on the site to abuse data that's stored there.

See, even though people should use different passwords on different systems, the reality is that don't.

...and since it's so easy to hash passwords, you have no excuses for not following industry best practices.

share|improve this answer
9  
You make what I believe to be the most important point: YOU and your workers should not have access to the user's password. Who cares about the hacker, it's the people holding the data that concerns users. –  Adam Davis Jan 30 at 19:06
1  
+1 for the fact that as a developer/admin you should not have access to your users' passwords. That in itself is reason enough. –  Matt Feb 4 at 20:51
add comment

Noticeable attacks like deleting data are usually the stuff of amateurs, and are the least of your worries. One of the first things an experienced attacker will do is attempt to gain legitimate access, so even if you patch the original vulnerability he used, he will still be able to get in. He will do everything possible to avoid drawing attention to himself until he accomplishes what he desires. By leaving passwords unhashed, you just potentially made his job a lot easier. You also made it harder to detect and isolate his future malicious behavior.

Also, not all compromises give you full shell access. What if the vulnerability an attacker used is just a read-only SQL injection on the users table? Leaving passwords unhashed just gave him pretty much full access.

That's in addition to the reasons given by other answers about your responsibility to safeguard your users' data. My point is, it's not just your users who have something to lose.

share|improve this answer
add comment

I have to post an answer here on a fallacy in the question itself. You are asking if passwords should be encrypted. No one encrypts passwords; no one, with the exception of services and programs like Firefox Sync and Roboform, whose sole purpose is to encrypt passwords.

Let's take a look at the definitions:

In cryptography, encryption is the process of encoding messages (or information) in such a way that only authorized parties can read it.

And hashing:

A hash function is any algorithm that maps data of arbitrary length to data of a fixed length.

In other words, encryption is a two-way conversion and hashing is a one-way conversion, so unless you are decrypting to view them later, this is not encryption.

Also, don't just hash, salt! Read this entire page before you hash your passwords.

As for hashing algorithms, which the OP is now looking into, I would suggest any of the high-end SHA-2 varients, such as SHA-384 or SHA-512.

And make sure to use rounds of hashing. Don't hash once, hash multiple times.

Consider reading this page to secure your login process more.

Second, your database can never be secure enough. There will always be security holes and ever-evolving risks. You should follow Murphy's Law and always prepare for the worst eventuality.

The other points pdr makes are exactly what else I would say: people who use the same password for every website, hackers using social engineering to gain more information, etc. etc.

share|improve this answer
    
+1 for hash plus salt. Cracking hashes without salts is sooo easy. –  Code Maverick Jan 30 at 16:27
3  
You know what's on the other side of a rainbow table @CodeMaverick? A pot of gold. –  NobleUplift Jan 30 at 16:36
    
In the context of password hashing MD5 has no known vulnerabilities beyond being fast, and that applies to SHA-2 as well. Using a slow, iterated construction is far more important than choosing SHA-2 over MD5. –  CodesInChaos Jan 31 at 14:06
4  
"Read this entire page before you hash your passwords" - that page mentions that you should not use rounds of hashing, but a hashing method that has been specifically designed to be as slow as necessary, such as PBKDF2. –  jhominal Apr 13 at 10:13
2  
Use SCrypt or PBKDF2, both of which are designed to be very expensive to perform in terms of either memory or CPU. Use a randomly generated Salt that you store on the user record. Do not perform multiple rounds of hashing, that just leads to collision issues. –  tom.dietrich Apr 14 at 14:54
add comment

There is an important principle at stake here. There is only one person who has any business knowing a users password. That's the user. Not their wife/husband, their doctor or even their priest.

It definitely does not include the programmer, database administrator or system technician responsible the the service they are using. That creates a challenge, as the programmer does have a responsibility to receive prove that the user actually knows the password, which is a non trivial problem to solve in a pure way.

The pure solution is to have a mechanism where the user is challenged with some new and unpredictable data, and then has to return a response that is based on this data and their password. One implementation of this would be to ask the user to digitally sign some newly generated data with their digital signature, and we could mathematically prove that they used the same cryptographic key pair that they used to originally create the account.

In practice, the pure solutions require substantial client side infrastructure and processing, and for many websites, this is often not appropriate for the data being protected.

A more common solution would be:

At the point where a password is first received in the application, the password is passed to hashing function, along with you application's random 'salt' value into the hash function.

The original string is then overwritten in memory, and from this point on, the salted hash is stored in the database or compared with the database record.

The key aspects that provide security here are:

  1. Knowledge of the hash does not directly provide authentication.
  2. Reverse calculation of the password from the hash is impractical.
  3. The use of rainbow tables (long lists of passwords and their calculated hashes) is made more challenging because the resulting hash is dependent on both username and password.
share|improve this answer
5  
In general it's preferred to use a random salt instead of the username. –  CodesInChaos Jan 30 at 11:24
    
Wow, great catch @CodesInChaos. I didn't notice that on my first read-through of the question. Yes, your salt should be randomly generated. It doesn't have to be some crazy blob stored in MySQL (and that would be bad because then it wouldn't be portable). Otherwise, +1 for saying that only the user should know the user's password. –  NobleUplift Jan 30 at 16:43
    
Okay, updated answer to suggest the application has its own random salt value. –  Ptolemy Jan 30 at 17:07
3  
No, the application doesn't have a salt value either. There should be a different, strongly random, salt value for each stored hash. (You store the salt alongside that hash.) That's what protects against statistical attacks. If you used the same hash for the entire application, then the same plaintext hashes to the same value. That's far worse than using the username as the hash. –  Ben Voigt Jan 31 at 0:00
    
It's not a web service, but SSH keypair authentication does use the 'pure' solution, where the server stores a public key and the user authenticates with a private key. –  cpast Jan 31 at 17:31
show 1 more comment

You need to "encrypt" (actually, "hash", for a proper notion of hashing) the passwords as a second layer of defence: this is meant to prevent an attacker, who got a read-only glimpse of the database, from escalating that into read-write access and, precisely, begin to alter the data. Read-only partial breaches happen in the real world, e.g. through some SQL injection attack from an account with read-only access, or by retrieving a discarded hard disk or old backup tape from a dumpster. I have written at length on this subject there.

As for the proper ways to hash passwords, see this answer. This involves salts, iterations, and, most of all, not inventing your own algorithms (homemade cryptography is a sure recipe for disaster).

share|improve this answer
    
+1 for knowing the difference between encryption and hashing. –  NobleUplift Jan 30 at 16:48
add comment

I agree with the answer from pdr, for the reasons stated in that answer.

I would add the following: you should do it because it is easy to do and generally accepted as best practice for any application. More specifically, passwords should always be salted and hashed before writing to any persistent storage. Here is a good reference on the importance of salting and choosing a good cryptographic hash (that also provides free source code in several popular languages): https://crackstation.net/hashing-security.htm

The small amount of extra development time is well worth the protection it provides your users, and to your reputation as a developer.

share|improve this answer
    
+1 for mentioning both salting, and hashing, as well as not mentioning encryption, which doesn't even belong in this question. –  NobleUplift Jan 30 at 16:49
add comment

I won't repeat what other people have said, but assuming you have PHP 5.3.8 or better, you should be using the PHP native bcrypt to store your passwords. This is built into PHP. If you have PHP 5.5 you can use the best available password constant. You can also use a library to make 5.3.8 or better behave like 5.5.

Stack Overflow question How do you use bcrypt for hashing passwords in PHP? explains it, and the other replies there explain more. Please don't mess around trying to do this yourself.

share|improve this answer
2  
Unfortunately, I'm using PHP 5.3.3 so your suggestions won't apply –  phpmysqlguy Jan 30 at 2:40
4  
is 5.3.3 to 5.3.8 much of an upgrade? –  gbjbaanb Jan 30 at 9:39
    
Any chance you are on Red Hat? Because they have backported the fix to bcrypt. If not, then use SHA256 instead of brcypt. –  Elin Jan 30 at 13:00
1  
Encryption and hashing are different things. Hash passwords, don't encrypt them. You never need to know them. You only need the user to be able to use the password to prove who he/she is. Hashing (with salt) allows this. Encryption, esp. symmetric encryption is wrong as it allows passwords to be recovered. –  Paul de Vrieze Jan 30 at 22:38
    
The one thing I'll add is that the good thing about the password_hash() function in php 5.5+ is that it handles the salting and so on sanely by default. Earlier than that you need to go ahead and use something like ircmaxell's library that backports it (he wrote the 5.5 implementation). Do not assume you can generate a random salt by yourself. It is very very hard and best left to experts; it is really easy to get random but not uniform results which are exploitable. –  Elin Jan 30 at 23:24
show 1 more comment

The scenario I can think of is that you are hacked.

Another scenario you need to think of: someone slipped your DBA (or whoever else can run select queries on your DB) $100, to give them the users' passwords. Or social engineers some intern to do that.

Then they use those passwords to log in to user's Gmail... or commerce site... (because people are ... less than smart shall we say - and use the same password across sites).

Then the irate user sues your company for exposing their password.


NOBODY (including people in your company) should be able to read plain text password. Ever. There's no legitimate business or technical need for that.

share|improve this answer
add comment

For one, even database administrators should not see the users' passwords. Hashing them will prevent this in case the administrator decides to look at a password and login into their users' account.

share|improve this answer
1  
this does not add anything worthy to what was already posted in prior answers –  gnat Jan 30 at 8:54
1  
+1. He actually said "hashing", instead of encryption like many others are. Also, he directly contradicted the OP who said he wanted the passwords plaintext to log into other users' accounts. –  NobleUplift Jan 30 at 16:24
add comment

Well, it's surprising no one has mentioned this, yet, but what about PHYSICAL security of your database?

You may have the best IT security in the world set up, but that doesn't stop anyone who can gain physical access to your storage media. What happens when your team wins the Superbowl this afternoon, and a small riot erupts in your city's downtown area where your office / hosting provider is? (Given that it's Seattle vs. Denver, two large IT areas in the US, I don't think that's unreasonable). The mob smashes in to your building and while the authorities are overwhelmed, someone grabs some of your hardware with a DB on it that contains clear-text passwords?

What happens when the Feds show up and seize your equipment because some high-level exec was using his position in the company to execute illegal stock trades? Then the Feds use those passwords to investigate your customers, although they did nothing wrong. Then they realize it was YOU that left them vulnerable.

What happens when your IT department forgets to wipe the old RAID drives that held your DB when they do scheduled replacements before "handing out" the old drives to interns, and then their dorm roommates find what was left behind, and figure out they can "sell" it and never have it traced back to them?

What happens when your DB Server blows a motherboard, IT restores an image to your new server, and the "carcass" of the old server gets thrown in the recycling heap? Those drives are still good, and that data is still there.

Any decent architect knows that security isn't something you "bolt on" later with firewalls and operations policies. Security has to be a fundamental part of the design from the very beginning, and that means passwords are one-way hashed, NEVER transmitted with out encryption (even inside your own datacenters), and never recoverable. Anything that can be retrieved can be compromised.

share|improve this answer
add comment

Setting aside the case of your database being hacked: As a customer I wouldn't want YOU to know my password. I know that you can easily catch the password when it comes in on a request, but I got a better feeling when you don't have it at your disposal for querying anytime you like.

share|improve this answer
1  
Actually, if the OP took it one step further and encrypted in JavaScript, then the hash would be sent over the wire and never be seen in the request. –  NobleUplift Jan 30 at 16:25
1  
In that case an attacker would only need to send the hash over the wire too. The hash would just function as a fancy but non-encrypted password, wouldn't it? (Edit: not if it had to be salted with a different salt each time, and the salt came from the server. I think) –  RemcoGerlich Jan 30 at 20:52
1  
@RemcoGerlich The key concept is known as a nonce which is used to avoid a replay attack. –  MichaelT Jan 31 at 21:23
add comment

If the passwords are stored in plain text it would mean that they're known to the user and whoever has access to that table. The whole idea about implementing users and passwords is to assure that a certain session in your system belongs to a said person, both for privacy and security reasons.

If a username/password is known by a group of people it becomes useless to unequivocally identify a person, and that creates a lot of possible scenarios for identity theft, fraud...

That's why passwords are stored using asymetric encryption protocols, to make sure that you can validate them without being capable of reading them.

share|improve this answer
2  
Who stores passwords using asymmetric encryption? That's public-key cryptography, which means even after I encrypt my password, it can be decrypted and read if someone ever obtains my private key. With hashing, I and only I know my password (unless I write it down or put it in a password manager, where it actually is asymmetric encryption). –  NobleUplift Jan 30 at 16:46
    
Please, check the wikipedia page for public-key cryptography: en.wikipedia.org/wiki/Public-key_cryptography "Public-key cryptography, also known as asymmetric cryptography," –  Alpha1983 Jan 30 at 19:02
1  
... yes, I said that using asymmetric encryption? That's public-key cryptography. What is your point? –  NobleUplift Jan 30 at 20:21
add comment

I think there's a fundamental flaw in the question. The fact is, there's no such thing as a "secure database". It should be taken as a given that there are flaws in your system somewhere that could allow malicious users access to arbitrary data on your servers. Heartbleed is an excellent case in point, being an exploit that was in the wild for over two years before it was noticed by researchers. You may have done everything you know how to do to protect the data, but you can't account for all of the other pieces of software you're using on your servers and the complicated ways that they interact.

If someone takes an interest in you, you will get hacked. It's important to do your best to prevent getting hacked in the first place, but also to mitigate the damage that is done when it happens by putting as many hurdles in place as possible. Hash your passwords. It's not that hard to set up, and you are doing your users a disservice by not taking their privacy seriously. It is hubris to think you are somehow better shielded against malicious attacks than companies like Yahoo, or Sony, or Target, all of whom have been hacked.

share|improve this answer
1  
this does not seem to offer anything substantial over 14 prior answers –  gnat Apr 13 at 5:23
    
I disagree otherwise I wouldn't have posted it. I'm not sure I see how your going around making negative comments adds to the conversation, though, aside from discouraging people to participate. –  lobati Apr 13 at 16:12
    
well don't know if you have read other answers prior to posting yours, but per my reading all the points here were already made (and per my reading better presented) elsewhere. Eg, point about flaw in the question has been made more than 2 months ago in this and this answer. Point about hashing passwords was made at least in 7 other answers. Point about making backups and accounting for possible problems in other pieces of the system was also made long ago. Etc etc –  gnat Apr 13 at 16:30
    
The fallacy point linked was different from mine. They were stating the difference in meaning between hashing vs encryption, whereas I was saying that it was a fallacy to think that a database could be considered "secure". I still don't see any other answers discussing other pieces of software and their interactions being insecure, and I didn't make any points about backups. –  lobati Apr 13 at 19:03
    
"assume you will be hacked" - that's how it was spelled in an answer posted over 2 months ago –  gnat Apr 13 at 19:42
show 1 more comment

protected by gnat Apr 13 at 5:22

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.