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.

But my question is this: 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, and starts deleting data.

Who’s important here?

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 information.

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 employs a common password, it will appear in reverse-hashing tables, which are readily available with a simple Internet search.

You’re worried about the small fry

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 you, or your current users, who have something to lose.

Hash and salt

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.

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.

Find more answers or leave your own answer at the original post. See more Q&A like this at Programmers, a question and answer site for professional programmers interested in conceptual questions about software development. If you've got your own programming problem that requires a solution, log in to Programmers and ask a question (it's free).

I have to ask... Why the hell do folks roll their own implementations for this type of thing! If you are not a security expert, etc. don't f'n make an account system yourself. You should be able to find strong implementations out in the world that you can integrate.

At minimum find and use a strong implementation to manage taking a users password and oneway hashing+salt, etc it for long term storage and later authentication.

I would also recommend not rolling your own password hashing scheme using primitives like SHA1 and salt but use a complete system specifically designed for the purpose like PBKDF2.

There is a general point to be made as a corollary to "It's not about you, its about your users privacy" and that is that you shouldn't keep any raw data about your users that isn't immediately needed for providing the service, you can't have a privacy breach (or subpoena) of data you don't have. That may mean scrubbing logs and deleting them aggressively after running whatever operational statistics you want, not processing your own credit cards, etc.

The fact that people out there are asking this question and have a Web service is absolutely fucking terrifying.

Yes. But they have to start somewhere, and we want good documentation to be accessible to them. In this case there are several existing Ars articles covering this, I doubt we can summarize them accurately in the comments section.

The fact that people out there are asking this question and have a Web service is absolutely fucking terrifying.

I really think the basics of encryption should be taught as a requirement for any programming course. The why's, the how's and the dangers of doing it wrong. Especially web programming, and anything that touches back-end services like databases.

I wouldn't even advertise being able to do back-end coding until I was confident in at least doing encryption basics like this right. Hash+salt, using the correct hashes or things like bcrypt/scrypt, etc.

On the other hand, if you're in a position to ask this question the way it was asked, you need to not be doing this yourself, because you're simply not ready. Continue to educate yourself until you are (at which point you'll hopefully realize this isn't a good RIY--roll-it-yourself--project), but seriously hand it off to someone else until you are. If that means paying someone else, then do it. You're too likely to screw up something basic if you're still at a point of [not] understanding to be asking questions like this... possibly even if you do incorporate a proper security library.

To start with, there is no such thing as a "secure database", except for /dev/null. (Which has the added advantage of being webscale!)

MySQL is a DBMS; a database is a collection of related data, a DBMS is the dozens of utilities that you install to manage that data, all of which need to be configured correctly, upgraded, monitored, etc.

That complexity is why, in practice, you can't simply declare "this is secure", and instead need redundant security measures.

Some answers recommend "hash and salt passwords!" That's not unreasonable, but doing it right is still *incredibly* hard.

My advice (and I am a security professional) is don't do it at all. Use OpenID, and let someone who has spent years perfecting their process store the actual credentials.

I would also recommend not rolling your own password hashing scheme using primitives like SHA1 and salt but use a complete system specifically designed for the purpose like PBKDF2.

Yup.

Really, the very first thing all these responses should say is: "Just use PBKDF2, bcrypt, or scrypt." And after that, explain why doing otherwise is a bad idea. Saying 'hashing + salt, and SHA is a good hash!' is rather negligent. The SHA family* are absolutely horrible for protecting passwords, and if you're asking a question about this sort of thing, you're certainly not qualified to be using SHA to build a Key Derivation Function yourself.

Unfortunately, there's just so much bad info out there. I just did a Google search for "php password", and multiple links gave examples using MD5. One of the links started with unsalted MD5, then went to the 'next level' with unsalted SHA256, next salted SHA256, and ended up with bcrypt at the very end of the article saying that's what you should use. Unfortunately, people would have likely just grabbed the first example and carried on with their business. And that's just the two links I bothered looking at on the first page of Google! MD5/SHA should either not be mentioned at all, or only in passing in the context of 'never ever ever use these to store passwords. Or I'll hit you'.

* I've not looked closely at SHA-3, but, IIRC, one of the requirements was to be able to be specify a work factor of some sort. But even then, it's better not to be dealing with the salt yourself, that's just one extra way for you to screw up.

I am going to take a slightly different tack than than answers so far: because you, yourself, cannot be trusted with users' passwords.

Oh, you think you can? How about when you expand beyond a one person operation - think you can trust your new partners/employees implicitly? Sure, you have met all of them, and maybe you are a perfect judge of character, but what happens when you hit it big and now your org is big enough that it is impossible for you to know everyone, and some Elbonian is offering your database administrator $1 per password on your million-user database... everyone has a price.

The point of all that is, a password is a kind of data that should be a secret to everyone but the person who owns it. With a reproducible hashing function there is no good reason for it to be stored anywhere in anything other than the hashed form, which is really better for everyone involved.

If someone believes that their database is secure, chances are they aren't as aware of how often code is compromised, or even the most basic exploits like SQL injection. Databases should be designed so that they don't give up any sensitive information, even when someone has the login information to get to it.

In the very specific case of passwords, it is now well-known that there is no legitimate reason to store passwords in any sort of reversible fashion. Encrypting passwords, while it offers some protection, isn't a good idea because if someone gets (or brute forces) the key they can reverse the encryption and retrieve the passwords.

These days, even a hashed password isn't enough. Going with something like PBKDF2 is much better, but being based on hash algorithms, it won't be long before it isn't even enough. Anyone can easily build a low-cost computer today that can calculate billions of hashes per second with off-the-shelf hardware. And while PBKDF2 offers more protection than a plain hash, any advancements made in hash calculation technology also directly affect performance of calculating PBKDF2 values as well.

The one nice thing about PBKDF2 is that it is designed to scale as hardware improves. So if you have to use something based on hashes, this is the way to go.

The problem is that hashes were never designed for handling passwords -- they are designed to quickly check the integrity of a data stream. As such they were designed to be fast, which is exactly what you don't want when someone is trying to crack passwords in your database -- you want as many speed bumps as possible. Using something that is intentionally slow is a much better choice. For someone implementing a system today, a low-performance algorithm is preferred. One based on bcrypt or scrypt, for example. Other solutions exist, but it's best to go with something well-known and well-tested.

Above all, unless you are truly a security expert, don't try to implement your own way of handling passwords. Let people who know mathematics, encryption, and security do the hard work. It's pretty much impossible not to make a critical mistake when attempting to design your own. Even the experts find it difficult.

Read up on the concept of translucent databases. The concept is that access control is a failed mechanism for securing data in today's information age and should only be used as a last ditch effort. Look at bitcoin, the entire ledger is in plain site but the system is secure. It doesn't require access control mechanisms, instead it relies on the individual incentives of participants in the system and tough encryption.

It's about recovery from failure. Sure, you design your database to be secure. You design your systems to be secure. But as all too many bugs and compromises have made clear, there's a lot of parts in your systems that aren't under your control that can render your systems insecure. And Murphy is always out there, waiting. Sooner or later, no matter what you do, some combination of circumstances will come about that lead to your database being compromised. If passwords were stored in the clear, every single user is now instantly compromised. But if you had them hashed and salted using a good method that'll be hard to break (eg. Bcrypt), it's another layer of protection that buys you enough time to inform your users and let them change their passwords before they're actually compromised.

A web site should never be able tell me my password!!! If they can I know that they have failed security 101. At that point they cannot be trusted to have done anything correctly! definitely no purchases, no credit cards...

Many times I will send the web master a message about poor practices.

The worst is when the web site "helpfully" sends me a welcome message which includes my username and password.

Next is a site that handles a lost login by emailing you your current password.

The fact that people out there are asking this question and have a Web service is absolutely fucking terrifying.

I really couldn't put it any better. It's like a dolt that barely possesses the mental capacity to have anything to do with IT suddenly came into money and decided to start his own facespace... I feel for the end users.

I'm a bit shocked that someone with - seemingly - enough knowledge to build a webservice can ask a question like this. First - there's Google. And secondly, when you build something you ought to read up on a bit more than scaffolding. And honestly, if you had asked google that question I'm quite certain you would have been able to get that same answer.

The fact that people out there are asking this question and have a Web service is absolutely fucking terrifying.

Yes. But they have to start somewhere, and we want good documentation to be accessible to them. In this case there are several existing Ars articles covering this, I doubt we can summarize them accurately in the comments section.

Yeah but some people really need to get a clue.

He's more worried about a hacker deleting data than accessing the data. Hello? Backups!?

Really, the very first thing all these responses should say is: "Just use PBKDF2, bcrypt, or scrypt." And after that, explain why doing otherwise is a bad idea. Saying 'hashing + salt, and SHA is a good hash!' is rather negligent. The SHA family* are absolutely horrible for protecting passwords, and if you're asking a question about this sort of thing, you're certainly not qualified to be using SHA to build a Key Derivation Function yourself.

Ultimately it's not good enough to just say "use pbkdf2". You have to use it properly, which means you have to understand how it works.

WEP encryption for wifi used a perfectly strong industry standard encryption algorithm, but they implemented it wrong so a brute force attack only takes minutes with weak hardware. The same mistakes are possible with pbkdf2 and scrypt.

I recommend listening to episodes 1 through 450 of the security now podcast. Any episode relating to hashes should be listened to twice.

They're ~100 minutes each so it'll take a while... But until then you should not even really be implementing a system that uses pbkdf2.

Another good option, if you don't want to learn how it works, is to create your system and post it to github to be reviewed by someone who knows their stuff. If your code is clean and you put a nice bounty on if at stack overflow, it should get some attention.

To whomever asked this question I have some other questions to ask you.

What is your goal with your web service? Are you wanting to make something that, eventually, millions of people will use? Or is it an internal service for a business?

If it's the public case you really need to get a good password library. Many people have pointed to PBKDF2. But at least hash the passwords. If it's internal you may be able to get by with just hashing. Keep in mind though that sometimes people will leave an organization on bad terms. They may have access to that "secure database".

Which brings to my next question. Why do you think your database is secure? The fact that you are asking about plain text passwords does not give me a good impression of your database security. When you mention that you are more concerned about recovering the database and not your users security it implies that you only care about making sure you can get the service up as soon as possible. While customers care about up-time they also care about security of their data.

Look at it this way. Say you live in a neighborhood where everyone gives each other spare keys. Breaking into one home means you have easy access to every other home.

The question shouldn't be why would you "encrypt" passwords, but why wouldn't you.

If you're doing some kind of even remotely social thing (and really, who isn't these days? I'm not, but I realize I'm an edge case) you should probably just use OpenID and forget about storing passwords and hashes entirely. Let someone else do it.

Tell me, why am I so utterly unsurprised that the questioner is named "phpmysqlguy?"

Dear god. I swear after reading 2 sentences I reflexively hit the deck as a PTSD reaction to a decade of fixing code written[1] by PHP "developers."

1. Saying "written" is sort of generous, it tends to arise more in the manner of slime mold growing larger on rotting detritus from places like "hotscripts" and the crackpot section at the bottom of every PHP "docs" page.

I've seen a lot of dumb questions on this StackOverflow series, but this takes the fucking cake.

And how. Still picking my jaw up off the floor.

And there are millions out there like this. Hopefully when the bubble pops a bit of Darwinism will come with it. (Yes, I'm aware there's a difference between ignorance and stupidity, and after over a decade in development, I just do not fucking care, and don't want to work with either.)

The fact that people out there are asking this question and have a Web service is absolutely fucking terrifying.

I really think the basics of encryption should be taught as a requirement for any programming course. The why's, the how's and the dangers of doing it wrong. Especially web programming, and anything that touches back-end services like databases.

I wouldn't even advertise being able to do back-end coding until I was confident in at least doing encryption basics like this right. Hash+salt, using the correct hashes or things like bcrypt/scrypt, etc.

Part of the issue here, I think, is that a lot of misguided kids go to school for a Computer Science degree thinking that they will be taught Software Engineering. Nothing could be further from the truth.

I was one of those kids, I made that mistake, and in the CS curriculum at my school, by far and away the one (1) software engineering class that was required was the most useful to me in my entire career.

Computer Science is about the science of computing, not about building software, and I think (probably just through apathy/incompetence) it's practically a bait-and-switch thing at this point - practically nobody tells developer hopefuls that they won't be taught hardly anything about the actual methods of building software in a CS curriculum, even at a lot of Research One universities.

Here is what I think about storing passwords in Six Simple Rules. (It's too long to repeat here, but essentially, encrypted in transit, hashed, salted, with an appropriate hash algorithm and a long salt.)

I have to say all the "don't even bother, just use something by others who know what they're doing" comments are boring.

It's perfectly possible to roll up some sane hashing and salting with very little effort and learn something while you're at it. And come up with something reasonably secure.

As long as the hashing algorithm is still designed and implemented by someone else, yes. I've implemented a highly reusable Java class for storing PBKDF2-hashed and salted passwords, with JPA annotations for immediate use with an ORM, and support for gradually increasing the number of hash iterations and other security parameters. Even with thorough documentation and generous whitespace, it was less than 100 lines. This is because the standard JRE includes PBKDF2 functionality.