If you use a GUID as a password for a publicly facing application as a means to gain access to a service, is this security through obscurity?
I think the obvious answer is yes, but the level of security seems very high to me since the chances of guessing a GUID is very very low correct?
Update
The GUID will be stored in a device, when plugged in, will send over the GUID via SSL connection.
Maybe I could generate a GUID, then do a AES 128 bit encrption on the GUID and store that value on the device?
In my opinion, the answer is no.
If you set a password to be a newly created GUID, then it is a rather safe password: more than 8 charcters, contains numbers, letters ans special characters, etc.
Of course, in a GUID the position of '{', '}' and '-' are known, as well as the fact that all letters are in uppercase. So as long as nobody knows that you use a GUID, the password is harder to crack. Once the attacker knows that he is seeking a GUID, the effort needed for a brute force attack reduces. From that point of view, it is security by obscurity.
Still, consider this GUID: {91626979-FB5C-439A-BBA3-7715ED647504} If you assume the attacker knows the position of the special characters, his problem is reduced to finding the string 91626979FB5C439ABBA37715ED647504. Brute forcing a 32 characters password? It will only happen in your lifetime, if someone invents a working quantum computer.
This is security by using a very, very long password, not by obscurity.
EDIT:
After reading the answer of Denis Hennessy, I have to revise answer. If the GUID really contains this info (specifically the mac address) in a decryptable form, an attacker can reduce the keyspace considerably. In that case it would definitely be security by obscurity, read: rather insecure.
And of course MusiGenesis is right: there are lots of tools that generate (pseudo) random passwords. My recommendation is to stick with one of those.
Actually, using a GUID as a password is not a good idea (compared to coming up with a truly random password of equivalent length). Although it appears long, it's actually only 16 bytes which typically includes the user's MAC address, the date/time and a smallish random element. If a hacker can determine the users MAC address, it's relatively straightforward to guess possible GUID's that he would generate.
If one can observe the GUID being sent (e.g. via HTTP Auth), then it's irrelevant how guessable it is.
Some sites, like Flickr, employ an API key and a secret key. The secret key is used to create a signature via MD5 hash. The server calculates the same signature using the secret key and does auth that way. The secret never needs to go over the network.
GUID is to prevent accidental collisions, not intentional ones. In other words, you are unlikely to guess a GUID, but it is not necessarily hard to find out if you really want to.
At first I was ready to give an unqualified yes, but it got me thinking about whether that meant that ALL password based authentication is security by obscurity. In the strictest sense I suppose it is, in a way.
However, assuming you have users logging in with passwords and you aren't posting that GUID anywhere, I think the risks are outweighed by the less secure passwords the users have, or even the sysadmin password.
If you had said the URL to an admin page that wasn't otherwise protected included a hard coded GUID, then the answer would be a definite yes.
I agree with most other people that it is better than a weak password but it would be preferable to use something stronger like a certificate exchange that is meant for this sort of authentication (if the device supports it).
I would also ensure that you do some sort of mutual authentication (i.e. have the device verify the servers SSL certificate to ensure it is the one you expect). It would be easy enough of me to grab the device, plug it into my system, and read the GUID off of it then replay that back to the target system.
In general, you introduce security vulnerabilities if you embed the key in your device, or if you transmit the key during authentication. It doesn't matter whether they key is a GUID or a password, as the only cryptographic difference is in their length and randomness. In either case, an attacker can either scan your product's memory or eavesdrop on the authentication process.
You can mitigate this in several ways, each of which ultimately boils down to increasing the obscurity (or level of protection) of the key:
Encrypt the key before you store it. Of course, now you need to store that encryption key, but you've introduced a level of indirection.
Calculate the key, rather than storing it. Now an attacker must reverse-engineer your algorithm, rather than simply searching for a key.
Transmit a hash of the key during authentication, rather than the key itself, as others have suggested, or use challenge-response authentication. Both of these methods prevent the key from being transmitted in plaintext. SSL will also accomplish this, but then you're depending on the user to maintain a proper implementation; you've lost control over the security.
As always, whenever you're addressing security, you need to consider various tradeoffs. What is the likelihood of an attack? What is the risk if an attack is successful? What is the cost of security in terms of development, support, and usability?
A good solution is usually a compromise that addresses each of these factors satisfactorily. Good luck!
It's better than using "password" as the password, at least.
I don't think a GUID would be considered a strong password, and there are lots of strong password generators out there that you could use just as easily as Guid.NewGuid().
It really depends on what you want to do. Using a GUID as password is not in itself security through obscurity (but beware the fact that a GUID contains many guessable bits out of the 128 total: there is a timestamp, some include the MAC address of the machine that generated it, etc.) but the real problem is how you will store and communicate that password to the server.
If the password is stored on a server-side script that is never shown to the end user, there is not much risk. If the password is embedded in some application that the user downloads to its own machine, then you will have to obfuscate the password in the application, and there is no way to do that securely. By running a debugger, a user will always be able to access the password.
Sure it is security by obscurity. But is this bad? Any "strong" password is security by obscurity. You count on the authentication system to be secure, but in the end if your password is easy to guess then it doesn't matter how good the authentication system is. So you make a "strong" and "obscure" password to make it hard to guess.
It's only security through obscurity to the extent that that's what passwords are. Probably the primary problem with using a GUID as a password is that only letters and numbers are used. However, a GUID is pretty long compared to most passwords. No password is secure to an exhaustive search; that's pretty obvious. Simply because a GUID may or may not have some basis on some sort of timestamp or perhaps a MAC address is somewhat irrelevant.
The difference in probability of guessing it and something else is pretty minimal. Some GUIDs might be "easier" (read: quicker) to break then others. Longer is better. However, more diversity in the alphabet is also better. But again, exhaustive search reveals all.
I recommend against using a GUID as a password (except maybe as an initial one to be changed later). Any password that has to be written down to be remembered is inherently unsafe. It will get written down.
Edit: "inherently" is inaccurate. see conversation in comments
Related
I'd like to use Windows.Security.Credentials.PasswordVault in my desktop app (WPF-based) to securely store a user's password. I managed to access this Windows 10 API using this MSDN article.
I did some experiments and it appears that any data written to PasswordVault from one desktop app (not a native UWP app) can be read from any other desktop app. Even packaging my desktop app with Desktop Bridge technology and thus having a Package Identity does not fix this vulnerability.
Any ideas how to fix that and be able storing the app's data secure from other apps?
UPDATE: It appeared that PasswordVault adds no extra security over DPAPI. The case is closed with a negative result.
(this is from what I can understand of your post)
There is no real way of preventing data access between desktop apps when using these kind of API's http://www.hanselman.com/blog/SavingAndRetrievingBrowserAndOtherPasswords.aspx tells more about it. You'd probably just want to decrypt your information.
memory access restriction is difficult, code executed by the user is always retrievable by the user so it would be difficult to restrict this.
have you considered using the Windows Data Protection API :
https://msdn.microsoft.com/en-us/library/ms995355.aspx
grabbed straight from the source
DPAPI is an easy-to-use service that will benefit developers who must provide protection for sensitive application data, such as passwords and private keys
WDPAPI uses keys generated by the operating system and Triple DES to encrypt/decrypt your data. Which means your application doesn't have to generate these keys, which is always nice.
You could also use the Rfc2898DeriveBytes class, this uses a pseudo-random number generator to decrypt your password. It's safer than most decrypters since there is no practical way to go back from the result back to the password. This is only really useful for verifying the input password and not retrieving it back again. I have never actually used this myself so I would not be able to help you.
https://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes(v=vs.110).aspx
see also this post which gives a way better explanation than I can.
How to securely save username/password (local)?
If I misunderstood the question in some way, tell me, I will try to update the answer.
NOTE that modern/metro apps do not have this problem, although they still are accessible in other ways.
The hard truth is that storing a password in a desktop application, 100% securely is simply not possible. However, you can get close to 100%.
Regarding your original approach, PasswordVault uses the Credential Locker service which is built into windows to securely store data. Credential Locker is bound to the user's profile. Therefore, storing your data via PasswordVault is essentially equivalent to the master password approach to protecting data, which I talk about in detail further down. Only difference is that the master password in that case is the user's credentials. This allows applications running during the user's session to access the data.
Note: To be clear, I'm strictly talking about storing it in a way that allows you access to the plain text. That is to say, storing it in an encrypted database of any sort, or encrypting it yourself and storing the ciphertext somewhere. This kind of functionality is necessary in programs like password managers, but not in programs that just require some sort of authentication. If this is not a necessity then I strongly recommend hashing the password, ideally per the instructions laid out in this answer by zaph. (Some more information in this excellent post by Thomas Pornin).
If it is a necessity, things get a bit more complicated: If you want to prevent other programs (or users I suppose) from being able to view the plaintext password, then your only real option is to encrypt it. Storing the ciphertext within PasswordVault is optional since, if you use good encryption, your only weak point is someone discovering your key. Therefore the ciphertext itself can be stored anywhere. That brings us to the key itself.
Depending on how many passwords you're actually trying to store for each program instance, you might not have to worry about generating and securely storing a key at all. If you want to store multiple passwords, then you can simply ask the user to input one master password, perform some salting and hashing on that, and use the result as the encryption key for all other passwords. When it is time for decryption, then ask the user to input it again. If you are storing multiple passwords then I strongly urge you to go with this approach. It is the most secure approach possible. For the rest of my post however, I will roll with the assumption that this is not a viable option.
First off I urge you not to have the same key for every installation. Create a new one for every instance of your program, based on securely generated random data. Resist the temptation to "avoid having to store the key" by having it be generated on the fly every time it is needed, based on information about the system. That is just as secure as hardcoding string superSecretKey = "12345"; into your program. It won't take attackers long to figure out the process.
Now, storing it is the real tricky part. A general rule of infosec is the following:
Nothing is secure once you have physical access
So, ideally, nobody would. Storing the encryption keys on a properly secured remote server minimizes the chances of it being recovered by attackers. Entire books have been written regarding server-side security, so I will not discuss this here.
Another good option is to use an HSM (Hardware Security Module). These nifty little devices are built for the job. Accessing the keys stored in an HSM is pretty much impossible. However, this option is only viable if you know for sure that every user's computer has one of these, such as in an enterprise environment.
.Net provides a solution of sorts, via the configuration system. You can store your key in an encrypted section of your app.config. This is often used for protecting connection strings. There are plenty of resources out there on how to do this. I recommend this fantastic blog post, which will tell you most of what you need to know.
The reason I said earlier not to go with simply generating the key on the fly is because, like storing it as a variable in your code, you rely exclusively on obfuscation to keep it secure. The thing about this approach is that it usually doesn't. However, sometimes you have no other option. Enter White Box cryptography.
White box cryptography is essentially obfuscation taken to the extreme. It is meant to be effective even in a white-box scenario, where the attacker both has access to and can modify the bytecode. It is the epitome of security through obscurity. As opposed to mere constant hiding (infosec speak for the string superSecretKey approach) or generating the key when it is needed, white box cryptography essentially relies on generating the cipher itself on the fly.
Entire papers have been written on it, It is difficult to pull off writing a proper implementation, and your mileage may vary. You should only consider this if you really really really want to do this as securely as possible.
Obfuscation however is still obfuscation. All it can really do is slow the attackers down. The final solution I have to offer might seem backwards, but it works: Do not hide the encryption key digitally. Hide it physically. Have the user insert a usb drive when it is time for encryption, (securely) generate a random key, then write it to the usb drive. Then, whenever it is time for decryption, the user only has to put the drive back in, and your program reads the key off that.
This is a bit similar to the master password approach, in that it leaves it up to the user to keep the key safe. However, it has some notable advantages. For instance, this approach allows for a massive encryption key. A key that can fit in a mere 1 megabyte file can take literally billions of years to break via a brute force attack. Plus, if the key ever gets discovered, the user has only themselves to blame.
In summary, see if you can avoid having to store an encryption key. If you can't, avoid storing it locally at all costs. Otherwise, your only option is to make it as hard for hackers to figure it out as possible. No matter how you choose to do that, make sure that every key is different, so even if attackers do find one, the other users' keys are safe.
Only alternative is to encrypt password with your own private key stored somewhere in your code. (Someone can easily disassemble your code and get the key) and then store encrypted password inside PasswordVault, however the only security you have is any app will not have access to password.
This is dual security, in case of compromised machines, attacker can get access to PasswordVault but not your password as they will need one more private key to decrypt the password and that will be hidden somewhere in your code.
To make it more secure, if you leave your private key on your server and expose an API to encrypt and decrypt password before storing in Vault, will make it most secure. I think this is the reason people have moved on to OAuth (storing OAuth token in PasswordVault) etc rather then storing password in vault.
Ideally, I would recommend not storing password, instead get some token from server and save it and use that token for authentication. And store that token in PasswordVault.
It is always possible to push the security, with miscellaneous encryption and storage strategies. Making something harder is only making the data retrieval longer, never impossible. Hence you need to consider the most appropriate level of protection considering execution cost x time (human and machine) and development cost x time aspects.
If I consider strictly your request, I would simply add a layer (class, interface) to cipher your passwords. Best with asymmetrical encryption (and not RSA). Supposing the other softs are not accessing your program data (program, files OR process), this is sufficient. You can use SSH.NET (https://github.com/sshnet/SSH.NET) to achieve this quickly.
If you would like to push the security and give a certain level of protection against binary reverse-engineering (including the private key retrieval), I recommend a small (process limited) encrypted VM (like Docker, https://blogs.msdn.microsoft.com/mvpawardprogram/2015/12/15/getting-started-with-net-and-docker/) based solution such as Denuvo (https://www.denuvo.com/). The encryption is unique per customer and machine based. You'll have to encapsulated you c# program into a c/c++ program (which acts like a container) that will do all the in-memory ciphering-deciphering.
You can implement your own strategy, depending on the kind of investment and warranty you require.
In case your program is a backend program, you can pick the best strategy (the only I really recommend) of all which is to store the private key at the client side, public key at backend side and have local deciphering, all transmitted password would be hence encrypted. I would like to remark that password and keys are actually different strategies to achieve the same goal: checking if the program talks to the right person without knowing the person's identity; I mean this: instead of storing passwords, better store directly public keys.
Revisiting this rather helpful issue and adding a bit of additional information which might be helpful.
My task was to extend a Win32 application that uses passwords to authenticate with an online service with a "save password" functionality. The idea was to protect the password using Windows Hello (UserConsentVerifier). I was under the impression that Windows surely has something comparable to the macOS keychain.
If you use the Windows Credential Manager APIs (CredReadA, CredWriteA), another application can simply enumerate the credentials and if it knows what to look for (the target name), it will be able to read the credential.
I also explored using DPAPI where you are in charge of storing the encrypted blob yourself, typically in a file. Again, there seems to be no way (except obfuscation) to prevent another application from finding and reading that file. Supplying additional entropy to CryptProtectData and CryptUnprotectData again poses the question of where to store the entropy (typically I assume it would be hard-coded and perhaps obfuscated in the application: this is security by obscurity).
As it turns out, neither DPAPI (CryptProtectData, CryptUnprotectData) nor Windows Credential Manager APIs (CredRead, CredWrite) can prevent another application running under the same user from reading a secret.
What I was actually looking for was something like the macOS keychain, which allows applications to store secrets, define ACLs on those secrets, enforce biometric authentication on accessing the secret, and critically, prevents other applications from reading the secrets.
As it turns out, Windows has a PasswordVault which claims to isolate apps from each other, but its only available to UWP apps:
Represents a Credential Locker of credentials. The contents of the locker are specific to the app or service. Apps and services don't have access to credentials associated with other apps or services.
Is there a way for a Win32 Desktop application to access this functionality? I realize that if a user can be brought to install and run a random app, that app could probably mimic the original application and just prompt the user to enter the secret, but still, it's a little disappointing that there is no app-level separation by default.
I know that security through obscurity is frowned upon and considered not really secure, but isn't a password security through obscurity? It's only secure so long as no one finds it.
Is it just a matter of the level of obscurity? (i.e. a good password well salted and hashed is impractical to break)
Note I'm not asking about the process of saving passwords (Assume they are properly hashed and salted). I'm asking about the whole idea using a password, which is a piece of information, which if known could compromise a person's account.
Or am I misunderstanding what security through obscurity means? I guess that's what I assume it to mean, that is there exists some information which if known would compromise a system (in this case, the system being defined as whatever the password is meant to protect)
You are right in that a password is only secure if it is obscure. But the "obsure" part of "security through obscurity" refers to obscurity of the system. With passwords, the system is completely open -- you know the exact method that is used to unlock it, but the key, which is not part of the system, is the unknown.
If we were to generalize, then yes, all security is by means of obscurity. However, the phrase "security through obscurity" does not refer to this.
Maybe it's easier to understand what Security-by-Obscurity is about, by looking at something that is in some sense the opposite: Auguste Kerckhoffs's Second Principle (now simply known usually as Kerckhoffs's Principle), formulated in 1883 in two articles on La Cryptographie Militaire:
[The cipher] must not be required to be secret, and it must be able to fall into the hands of the enemy without inconvenience.
Claude Shannon reformulated it as:
The enemy knows the system.
And Eric Raymond as:
Any security software design that doesn't assume the enemy possesses the source code is already untrustworthy.
An alternative formulation of that principle is that
The security of the system must depend only of the secrecy of the key, not the secrecy of the system.
So, we can simply define Security-by-Obscurity to be any system that does not follow that principle, and thus we cleverly out-defined the password :-)
There are two basic reasons why this Principle makes sense:
Keys tend to be much smaller than systems, therefore they are easier to protect.
Compromising the secrecy of a key only compromises the secrecy of all communications protected by that key, compromising the secrecy of the system compromises all communications.
Note that it doesn't say anywhere that you can't keep your system secret. It just says you shouldn't depend on it. You may use Security-by-Obscurity as an additional line of defense, you just shouldn't assume that it actually works.
In general, however, cryptography is hard, and cryptographic systems are complex, therefore you pretty much need to publish it, to get as many eyeballs on it as possible. There are only very few organizations on this planet that actually have the necessary smart people to design cryptographic systems in secrecy: in the past, when mathematicians were patriots and governments were rich, those were the NSA and the KGB, right now it's IBM and a couple of years from now it's gonna be the Chinese Secret Service and international crime syndicates.
No. Let's look a definition of security through obscurity from wikipedia
a pejorative referring to a principle in security engineering, which attempts to use secrecy (of design, implementation, etc.) to provide security.
The phrase refers to the code itself, or the design of a system. Passwords on the other hand are something a user has to identify themselves with. It's a type of authentication token, not a code implementation.
I know that security through obscurity is frowned upon and considered not really secure, but isn't a password security through obscurity? It's only secure so long as no one finds it.
In order to answer this question, we really need to consider why "security through obscurity" is considered to be flawed.
The big reason that security through obscurity is flawed is that it's actually really easy to reverse-engineer a system based on its interactions with the outside world. If your computer system is sitting somewhere, happily authenticating users, I can just watch what packets it sends, watching for patterns, and figure out how it works. And then it's straightforward to attack it.
In contrast, if you're using a proper open cryptographic protocol, no amount of wire-sniffing will let me steal the password.
That's basically why obscuring a system is flawed, but obscuring key material (assuming a secure system) is not. Security through obscurity will never in and of itself secure a flawed system, and the only way to know your system isn't flawed is to have it vetted publicly.
Passwords are a form of authentication. They are meant to identify that you are interacting with who you are supposed to interact with.
Here is a nice model of the different aspects of security (I had to memorize this in my security course)
http://en.wikipedia.org/wiki/File:Mccumber.jpg
Passwords are an aspect of the confidentiality aspect of security.
While probably the weaker of the forms of authentication (something you know, something you have, something you are), I would still say that it does not constitute security through obscurity. With a password, you are not trying to mask a facet of the system to try to keep it hidden.
Edit:
If you follow the reasoning that passwords are also a means of "security Throguh Obscurity" to it's logical end then All security, including things like encryption, is security through obscurity. Then that means, the only system that is not secured through obscurity is one that is surrounded in concrete and sunk to the ocean floor, no one ever being allowed to use it. This reasoning, however, is not conducive to getting anything done. Therefore we use Security Through obscurity to describe practices that use not understanding the implementation of a system as a means of security. With passwords, the implementation is known.
No, they are not.
Security through obscurity means that the process that provides the access protection is only secure because its exact details are not publicly available.
Publicly available here means that all the details of the process are known to everyone, except, of course, a randomized portion that constitutes the key. Note that the range from which keys can be chosen is still known to everyone.
The effect of this is that it can be proven that the only part that needs to be secret is the password itself, and not other parts of the process. Or conversely, that the only way to gain access to the system is by somehow getting at the key.
In a system that relies on the obscurity of its details, you cannot have such an assurance. It might well be that anyone who finds out what algorithm you are using can find a back door into it (i.e. a way to access the system without the password).
The short answer is no. Passwords by themselves are not security by obscurity.
A password can be thought of as analogous to the key in cryptography. If you have the key you can decode the message. If you do not have the key you can not. Similarly, if you have the right password you can authenticate. If you do not, you can not.
The obscurity part in security by obscurity refers to how the scheme is implemented. For example, if passwords were stored somewhere in the clear and their precise location was kept a secret that would be security by obscurity. Let's say I'm designing the password system for a new OS and I put the password file in /etc/guy/magical_location and name it "cooking.txt" where anyone could access it and read all the passwords if they knew where it was. Someone will eventually figure out (e.g. by reverse engineering) that the passwords are there and then all the OS installations in the world will be broken because I relied on obscurity for security.
Another example is if the passwords are stored where everyone can access them but encrypted with a "secret" key. Anyone who has access to the key could get at the passwords. That would also be security by obscurity.
The "obscurity" refers to some part of the algorithm or scheme that is kept secret where if it was public knowledge the scheme could be compromised. It does not refer to needing a key or a password.
Yes, you are correct and it is a very important realisation you are having.
Too many people say "security through obscurity" without having any idea of what they mean. You are correct in all that matters is the level of "complexity" of decoding any given implementation. Usernames and passwords are just a complex realisation of it, as they greatly increase the amount of information required to gain access.
One important thing to keep in mind in any security analysis is the threat model: Who are you worried about, why, and how are you preventing them? What aren't you covering? etc. Keep up the analytical and critical thinking; it will serve you well.
I'm trying to figure out if it is alright to store passwords that are encrypted using the AES algorithm rather than storing passwords that are salted and hashed with SHA1.
The reason I am wondering this is because my company is in the middle of updating our membership system which is included with our proprietary CMS. Currently, we use AES encryption for passwords. This allows us to easily look up Admin passwords when customers call in for support. When we have staff changes, it is policy to change all admin passwords. The password lookup tool allows us to get the new passwords easily and our work flow isn't interupted.
I get the impression that most people think that hashing salted passwords is the more secure way of handling passwords but I can't figure out a way to comply with current company operations when using hashed passwords. And, the corporate cultural shift required to change our password operations probably won't happen unless I can give them some very compelling reasons to hash passwords.
Is a hashed password generally accepted as required versus an encrypted password? Why?
Encrypting passwords with a reversible encryption is of dubious value.
Obviously the lookup program has access to the key. That means you should assume that anyone who has access to the program also has access to the key. If you are paranoid you should also assume that their spouses, significant others, roomates, etc all have access to that key. Also anyone who has ever broken into the network ever in the past (since key was used) also has access to the key.
The problem with using a system like that is you will never know it is broken. Do I have access to the key? Right now? Can I lookup the password at anytime? As soon as you change it I know what it was changed to?
Using salted hash (vs reversible encyrption) presents its own challenges in implementation but you can be assured that stealing the password list is of little value (if properly implemented with a strong algorithm, multiple rounds, min password standards, and random per record salt). Your current system is "feel good encryption". While it may makes management "feel" safe they aren't actually being safe. It is marginally better than storing passwords in plaintext or on a sticky note it is at best a minimal speed bump to a determined attacker. The largest problem is you can never prove you are "safe" and may not have any warning when you are compromised. You could be compromised right now and not know it.
You mean, inside an application which stores passwords for user authentication.
Normally the motivation for hashing them vs storing encrypted is that it prevents someone who has stolen the database or compromised the server from obtaining the passwords.
If you encrypt them with AES, you're clearly going to have to keep the key somewhere, and can't ever change it (unless of course, you decrypt them all and re-encrypt).
If someone compromises the machine, they can obtain the key, as it is necessarily kept (at least) in memory at some time to decrypt the passwords.
It's either that, or use some fancy PKI. AES is a symmetric cipher.
Encrypting the passwords won't really help the application defend its database against any but the most casual attackers (as an attacker MUST be able to obtain the key). Hashing them makes it difficult for the cleartext to be obtained if passwords are strong.
If a hacker has access to the hashes in my DB, he has access to the rest of the information in the DB anyways. So why would he bother trying to decrypt the passwords? Should I be storing the passwords on a different server to the rest of my data? That is the only scenario in which I can envision it being useful.
Sometimes a hacker doesn't get full access to your DB. Sometimes they find a little SQL injection hole or other weakness that someone didn't code correctly, and so they can only do simple things at first like print out database cells one at a time. If they can print out a real password all of a sudden things get much worse.
Things happen: backup tapes are lost, accidentally thrown away, or stolen. A retired system wasn't wiped properly. A breach elsewhere leads to accidental exposure of a database. If a hacker gets access to a snapshot like this he can learn a lot about your system. But if the passwords are still hashed he can't also use the system to do something malicious, like log in as a different user and start changing things.
I've heard that most hacks are an inside job. Better to remove the ability even for people you trust to log in as others.
It's not about just you. Users tend to share passwords across systems. Maybe some day (God forbid) you have a breach that has nothing to do with passwords, but in the course of that breach your authentication tables will be one of the attacker's targets. If you store passwords in plain-text, you have also just compromised user accounts at many other services, and your very bad day just got quite a lot worse.
If you think this kind of thing doesn't happen, go talk to the guys at reddit.
People often use the same username/password for different accounts on other websites (including, e.g., online access to bank accounts).
Once you've discovered this hack and have secured your database, the hacker will still have the ability to login to your user's accounts.
Best security practices suggest:
You should use a unique (userId, password) pair for each account you have. But most people use a single pair for many resources (email, bank, etc). An attacker can steal them from one resource and use them to access another. Hashing the passwords with salt—see http://en.wikipedia.org/wiki/Salt_(cryptography)—prevents this sort of attack.
You should encrypt all sensitive data in your database, not just passwords. Your point that someone might steal your entire DB (or your server) is perfectly valid.
You should separate your web server from your database and any other precious resources, to quarantine an attack to your least valuable asset.
There are business reasons to hash passwords, as well. Remember, hashing means you do not store your users' passwords anywhere on your equipment.
Depending on the laws that apply, you may be required to do this in certain situations.
You greatly reduce your exposure if your data is stolen.
You're safer from social engineering attacks, in which an attacker impersonates a valid user and cajoles an employee into revealing a password. See http://en.wikipedia.org/wiki/Social_engineering_(security).
Should I be storing the passwords on a
different server to the rest of my
data?
This adds complexity to your system, but if it's something you can do it's definitely an improvement.
Note that using authentication servers such as Kerberos, RADIUS, or Windows domain authentication effectively put you passwords on another server.
Because even if you have access to the data, having access to the APPLICATION is actually more important. The Application makes it much easier to manipulate the data, for example.
Hashing the password prevents casual exposure from all eyes.
For example, you may well have the same password across several sites. A quick glance at the DB not only compromises your application, but perhaps several others.
It's just a good, solid practice to hash you passwords.
Mainly because it's nearly trivial to do it well, and the benefits can be very high.
Sometime, you don't know who will be the system administrator. You still want to protect your users from them.. So, by hashing passwords and all important information (such as credit card), you make it really harder for the hacker or administrator. And, I think password should never be written literally. I mean, I used a password since 2 years and I have never seen it written down.. why an administrator that I don't know should see MY password ?!
Using a hashed password prevents the attacker from being able to log into your app even if they know the hash. Your login page asks for the original password, so to log in using it, they'd have to reverse the hash (compute a collision). Using a rainbow table, that's fairly trivial for MD5, for example, which is where salting comes in. Then the attacker needs to know 1) the way you combine the salt and the password (not much security there), 2) the salt (which is likely in the db already) and 3) they have to compute that value for each combination of password and salt. That's a lot more than just computing hashes of common passwords and looking for a match.
When a hacker access your database it does not mean that he can access the procedural code, those procedures can alter databases outside the hacked database boundaries or inclusive can alter other procedures.
By the way now I´m going to ask you something: If a user is hacked and someone has his or her password, how do you make clear that it is not your application or security fault?
If you don't have stored passwords you don't have such responsability!
If an application is to show grade information at the university then having access to the password will allow you to get the grades for that person. If the password also allows you to log into the online course system then you can submit tests as that user.
If the data is even more sensitive, such as credit card numbers or health records, you are open to lawsuits.
Odds are that the more sensitive information may be on a more secured system, behind stronger firewalls, so they may have found a weakness by hacking into the authentication database.
By hashing the password, then those that have access to the authentication database can't see the password and so log into the very sensitive system as a different user.
The whole LinkedIn "scandal" was all about leaked hashed passwords.
As I see it, security isn't about anything other than making data retrieval inconvenient.
And by inconvenient in the ideal case we mean it'll take you millions of compute years to access (ie single CPU trying to guess at password would take on the scale of millions of years).
If you store passwords in cleartext, that takes a total of 0 compute years to access. The LinkedIn scandal would have looked much worse. All you have to do is SELECT * FROM USERS (either via injection or an insider).
People often reuse passwords, so if people learn your password, it means a whole world of data becomes accessible to them (not just their LinkedIn, for example). So it becomes a very personal risk. As a webmaster it's rude not to at least hash passwords: you don't have that much respect for your users to take the basic step of trying to protect their information.
Even if the hashed password can be cracked, you're at least taking the bare minimum step to protect your users.
If he can decrypt the passwords, he can probably get access to your user's accounts on other sites as well (as, no matter how many times we tell people not to re-use passwords, they do). Storing plaintext passwords is a good way to give away all your users' PayPal, eBay & Amazon accounts.
I'm already using salted hashing to store passwords in my database, which means that I should be immune to rainbow table attacks.
I had a thought, though: what if someone does get hold of my database? It contains the users' email addresses. I can't really hash these, because I'll be using them to send notification emails, etc..
Should I encrypt them?
Bruce Schneier has a good response to this kind of problem.
Cryptography is not the solution to your security problems. It might be part of the solution, or it might be part of the problem. In many situations, cryptography starts out by making the problem worse, and it isn't at all clear that using cryptography is an improvement.
Essentially encrypting your emails in the database 'just in case' is not really making the database more secure. Where are the keys stored for the database? What file permissions are used for these keys? Is the database accesable publically? Why? What kind of account restrictions are in place for these accounts? Where is the machine stored, who has physical access to this box? What about remote login/ssh access etc. etc. etc.
So I guess you can encrypt the emails if you want, but if that is the extent of the security of the system then it really isn't doing much, and would actually make the job of maintaining the database harder.
Of course this could be part of an extensive security policy for your system - if so then great!
I'm not saying that it is a bad idea - But why have a lock on the door from Deadlocks'R'us which cost $5000 when they can cut through the plywood around the door? Or come in through the window which you left open? Or even worse they find the key which was left under the doormat. Security of a system is only as good as the weakest link. If they have root access then they can pretty much do what they want.
Steve Morgan makes a good point that even if they cannot understand the email addresses, they can still do a lot of harm (which could be mitigated if they only had SELECT access)
Its also important to know what your reasons are for storing the email address at all. I might have gone a bit overboard with this answer, but my point is do you really need to store an email address for an account? The most secure data is data that doesn't exist.
I realize this is a dead topic, but I agree with Arjan's logic behind this. There are a few things I'd like to point out:
Someone can retrieve data from your database without retrieving your source code (i.e. SQL injection, third-party db's). With this in mind, it's reasonable to consider using an encryption with a key. Albeit, this is only an added measure of security, not the security...this is for someone who wants to keep the email more private than plaintext,
In the off chance something is overlooked during an update, or an attacker manages to retrieve the emails.
IMO: If you plan on encrypting an email, store a salted hash of it as well. Then you can use the hash for validation, and spare the overhead of constantly using encryption to find a massive string of data. Then have a separate private function to retrieve and decrypt your emails when you need to use one.
In common with most security requirements, you need to understand the level of threat.
What damage can be done if the email addresses are compromised?
What's the chance of it happening?
The damage done if email addresses are REPLACED could be much greater than if they're EXPOSED. Especially if you're, for example, using the email address to verify password resets to a secure system.
The chance of the passwords being either replaced or exposed is much reduced if you hash them, but it depends what other controls you have in place.
I would say it depends on the application of your database.
The biggest problem is, where do you store the encryption key? Because if the hacker has excess to anything more than your DB, all your efforts are probably wasted. (Remember, your application will need that encryption key to decrypt and encrypt so eventually the hacker will find the encryption key and used encryption scheme).
Pro:
A leak of your DB only will not expose the e-mail addresses.
Cons:
Encryption means performance loss.
Allot of database actions will be harder if not impossible.
Don't accidentally conflate encryption with obfuscation. We commonly obfuscate emails to prevent spam. Lots of web sites will have "webmaster _at_ mysite.com" to slow down crawlers from parsing the email address as a potential spam target. That should be done in the HTML templates -- there's no value to doing this in persistent database storage.
We don't encrypt anything unless we need to keep it secret during transmission. When and where will your data being transmitted?
The SQL statements are transmitted from client to server; is that on the same box or over a secure connection?
If your server is compromised, you have an unintentional transmission. If you're worried about this, then you should perhaps be securing your server. You have external threats as well as internal threats. Are ALL users (external and internal) properly authenticated and authorized?
During backups you have an intentional transmission to backup media; is this done using a secure backup strategy that encrypts as it goes?
Both SQL Server and Oracle (and I believe also others DBs) support encryption of data at the database level. If you want to encrypt something why don't simply abstract the access to the data that could be encrypted on the database server side and left the user choose if use the encrypted data (in this case the SQL command will be different) or not. If the user want to user encrypted data then it can configure the database server and all the maintenance work connected with key management is made using standard DBA tool, made from the DB vendor and not from you.
A copy of my answer at What is the best and safest way to store user email addresses in the database?, just for the sake of the search...
In general I agree with others saying it's not worth the effort. However, I disagree that anyone who can access your database can probably also get your keys. That's certainly not true for SQL Injection, and may not be true for backup copies that are somehow lost or forgotten about. And I feel an email address is a personal detail, so I wouldn't care about spam but about the personal consequences when the addresses are revealed.
Of course, when you're afraid of SQL Injection then you should make sure such injection is prohibited. And backup copies should be encrypted themselves.
Still, for some online communities the members might definitely not want others to know that they are a member (like related to mental healthcare, financial help, medical and sexual advice, adult entertainment, politics, ...). In those cases, storing as few personal details as possible and encrypting those that are required (note that database-level encryption does not prevent the details from showing using SQL Injection), might not be such a bad idea. Again: treat an email address as such personal detail.
For many sites the above is probably not the case, and you should focus on prohibiting SELECT * FROM through SQL Injection, and making sure visitors cannot somehow get to someone else's personal profile or order information by changing the URL.
It's worth to encrypt data in Databases, it's not making it a bit more difficult but way more difficult when its encrypted in the right way so stop philosophy and encrypt the sensitive data ;)
#Roo
I somewhat agree to what you are saying but isn't it worth encrypting the data just to make it a little more difficult for someone to get it?
With your reasoning, it would be useless to have locks or alarms in your house, because they can also easily be compromised.
My reply:
I would say that if you have sensitive data that you don't want to fall in the wrong hands, you should probably do it as hard as you can for a hacker to get it, even if it's not 100% fool proof.
I miss one important answer here.
When you have European users, you have to comply with the GDPR rules.
Email addresses are considered personal data meaning Art.5 does apply on email addresses.
processed in a manner that ensures appropriate security of the
personal data, including protection against unauthorised or unlawful
processing and against accidental loss, destruction or damage, using
appropriate technical or organisational measures (‘integrity and
confidentiality’).
Of course this does not say that you must encrypt email addresses. But by encrypting the data you do protect it from snooping employees. And protect yourself as a developer from requests to make a manual change in the database.
You really have to weigh your worst case senario of someone obtaining those email addresses, the likelihood of someone obtaining them, and your extra effort/time needed to impliement the change.