Store Encrypted Username Hash in Database - database

I'm currently working on basic user authentication for an app I'm putting together, and I don't have much experience with security.
This said, I understand the practice (and necessity) of salting/storing a (salted) password hash in a database as a blob, as opposed to the password (encrypted or no). I've already implemented this.
Is there anything to be gained by salting/hashing a user name and storing the hash in the database, as opposed to the username in plain-text (or encrypted)? It strikes me this would make it quite a bit harder to determine which users may access the system using the database for authentication.
Since it's vital to make it difficult for someone to crack the password for a user account, wouldn't it also make sense to increase the difficulty for determining which users are viable?
Edit: it's possible some of the language I'm using isn't 100% correct: feel free to correct :-)
Edit2: I changed one of my first points to indicate salting hashes -- thanks everyone for pointing out that I missed this :-)
Edit3: Removed wording indicating I am encrypting/decrypting a password. I'm using salted hashes and am storing that in the DB -- thanks Scotty for pointing this out.

It depends on the context
It's important to assess the sensitivity of the material you're serving. To dig deeper, I'll provide a few use cases.
Scenario 1: A social networking application
All of your user's interactions happen in the public. Their email address will be used as their username. There username is not considered private because their name appears in all their posts. The username may be searched by other users and/or email invites are enabled.
Verdict - Hashing = Bad
Scenario 2: An E-Commerce site
The user may or may not participate in public interactions (ex. commenting, reviews). Using an email address as the username is probably a bad idea because, through the use of password recovery, a compromised email account means a compromised user account on your site.
There is a lot of gray area here that is typically exploited for 'convenience.' If your site uses email as the user name, stores shipping history, and credit card numbers; a compromised email could mean a lot of identity theft troubles for your user.
In this case, using a policy where the username is not the user's email address is probably a good idea. Hashing the email adds no value.
Note: I'm looking at you Amazon.com.
Verdict: Common Practice != good practice
Scenario 3: A porn site
Make the username a pseudonym and the login name the user's email address. They may feel inclined to talk about the content and don't necessarily want their name to show up on Google's results for a smut site.
Assume the worst here. If somehow your database is hacked, the exposing of your user's identities could cause irreparable harm. Don't think this could happen to you? Take a look at this article.
Not only are their user's accounts hacked and passwords exposed but, there's a good chance a lot of those users used the same password on their email accounts. Now their info is posted anonymously on PasteBin for the whole world to see. Even worse, most of them probably don't even know this has happened yet.
By simply hashing both the username and password, they would have saved themselves and their users a whole lot of trouble.
Verdict: Definitely hash the email address whether or not it's used as the username.
Scenario 4: A bank
It should go without saying that no expense should be spared when it comes to banking/financial sites.
Security can be increased by:
Using a username other than the email address
Forcing a unique username by requiring numbers and letters
Hashing passwords
Requiring 2-point authentication (in case the user's email password is compromised)
Hashing email addresses
etc...
No expense should be spared to protect your users because, to not do so, means you're gambling with their livelihood.
Conclusion:
There is no hard and fast rule for security that applies to all sites. In some cases, the username is made public so hashing it adds no value. In others, not hashing it could cause irreparable harm. If you do end up developing a site where a username/email hash could be made useful here's a good approach.
Hash the username
Generate a unique salt for the user
Hash the password using the salt
Store the password with the salt in the database
By not hashing the username with a salt you avoid the chicken/egg problem. Unless you use a static salt for all of the usernames.
Keep in mind that a static salt for all the user accounts may be found out by reading the code. Once a static salt is found out, it'll essentially be useless when a rainbow table attack is employed. If you salt the passwords, generate a dynamic salt and store it along with the rest of the user's credentials in the database.
If you want hard/fast rules for simplicity here are a few good assumptions to remember:
Assume your database may be compromised at some point
Assume your source code will be compromised at some point
Assume your user's email will be compromised at some point
Assume your user's are dumb and use the same password for your site as they use for their email
Assume that hackers are smart/resourceful and financially driven.
If you choose to store sensitive/private data, then going the extra step may save you a PR/legal nightmare in the future.
Update:An interesting article about seed hashing just showed up on Coding Horror.

Short answer: most likely no.
Long answer: Your situation seems to lack the key "my usernames are sensitive because of ..." which raises the question: "Why? What is the specific, demonstrable problem that protecting usernames would solve?"
Without that problem, what you are describing is a common pitfall in security-related development (and really development as a whole): coming up with some idea to secure or obfuscate some part of the system, and then searching for a reason to use it. As with anything in software development, you should avoid doing anything other than exactly what is needed until a clear problem presents itself that can only be solved by using a specific tool.
Extra hint (for free!): salt your password hashes. Plain-old hashes are far less secure.

If you salted & hashed the username, you'd leave yourself with a bit of a chicken & egg problem.
If you salted & hashed the username, how would you find it in the database? You'd need to look up the user's record to find the salt you used to hash the username...

Probably not. Think of it this way - the username is the application's way of figuring out which account a user is trying to login as. The password is the application's way of figuring out whether the user is actually allowed to login as that account. In practice, this means you're going to look up a row in your accounts table using the username as an index. By encrypting the username, you're simply making it harder to find the right row.
However, if you're using the same encryption scheme to encrypt the username and password, they are pretty much equally secure - if you can break one, you can break the other. Thus, encrypting both makes it harder to lookup the user, but doesn't add any additional security.
Note: In your question you talk about decrypting your password field. You probably want to make this impossible (literally). Most people encrypt their passwords using a one-way hash function of some sort (MD5 and SHA256 are popular), along with a salt. The "one-way" part simply means that once you run something through the function, you can't use what you get out to get what you started with. However, if you start with the same input, you'll always get the same output. The salt is a secret that only your application knows (sort of like an encryption key), which is added to whatever you are encrypting, before it is run through the one-way hash. This makes it impossible to do things like match two encrypted passwords from two different sites (assuming they're using different salts).

It's not very fair to your users to store their password in plain text since everybody that has access to your database can see their passwords. You should use a salted hash.
Salt_(cryptography)

You can never properly evaluate the security of a system by looking at a single part of it in isolation. Whereabouts are you storing the key to decrypt the passwords?
Do the people that have access to the database also have access to the location you are storing the encyption key? If so you've only gained a minor improvement in security by encrypting the passwords and probably nothing much more to gain by encrypting the usernames.
If the decryption key and program using it are more secure than the database - which is pretty unusual, normally the database is in the most secure spot possible - then there would possibly be additional benefit to also encrypting the username as you'd be depriving attackers of useful information in brute force attacks.

Related

How does a password manager give users access to their passwords in clear text

As the title suggests, I am indeed working on a personal password manager. I have seen a large number of questions posted here with most answers being "Don't do it, use an existing solution that's proven like Bitwarden, Keepass, Dashlane, etc." and I understand the reasoning. If you're unsure of the mechanics that need to be put in place, the result won't be secure and it'll be a major security risk.
However, someone one day decided to create a password manager from scratch and eventually built a business from it so technically anyone can (with the right questions and skills). Anyway, I'm not trying to build a business but I am using this as a programming exercise (could have thought of something simpler in hindsight).
Here is what I "know":
Never store passwords in clear text (Should be obvious to anyone)
Use a master password to protect the entirety of the password database
Don't use a hash without at least a salt (same input gives same hash)
The password manager should NEVER have access to the clear text password (passwords should be encrypted on the client side)
For a basic visualisation, lets assume we are working with this database structure:
Username | Salt | Hashed_Password
---------------------------------
User_1 | 1SIO | FBVDVS156FSD615
User_2 | 5F54 | GDFG50684SD54DS
....
As mentioned, the Hashed_Password here is generated from the original password and the user's Salt.
What I would like to know, or at least understand:
How would (or does) a password manager give users the ability to autofill forms online or even simpler, visualise their stored passwords ?
I understand how to store passwords securely but the retrieval is what I'm struggling to get my head around
In my mind, anything that needs to display clear text passwords for the user (the password manager interface for example) should be done client-side and the password manager should never have access to the clear text password but the whole point of storing a hashed password is that hashing is irreversible (unless you plan on bruteforcing the whole thing)
Many other responses to this type of question involved encrypting with an asymmetric encryption (which I'm not against personally).
Thanks in advance for your answers !

Is it beneficial to encrypt usernames stored in the database?

The first & accepted answer on this question about passwords management suggests to encrypt the user identifiers in DB.
The good point is that if anyone gets a password, he has to know how to decrypt the user login to get the full login/password pair.
Some disadvantages I see, for example:
you have to decrypt user logins every time you want to display them
if you want to do a 'begins with' search on user login to find users, you cannot simply use LIKE '...%'
ORDER BY on login field may be quite difficult too...
What would you recommend (encrypt user identifiers or not)?
As usual, the answer is "it depends".
In general, I'd say that if an attacker has access to your database, your security situation is so badly compromised that encrypting the passwords will likely do you no favours. This is different to using a one-way hash - it's likely that an attacker who has access to your database also has access to your decryption key, whereas one-way hashes, by definition, are one way.
As you already say, it's likely that you will need regular access to the userIDs (esp. if you use email addresses as user IDs); in that case, again, an attacker who can read your database likely can intercept the unencrypted data.
So, if you work for a bank, the government, or any other place where data security has to be at the very top of the list, this additional protection may just be worth it, especially if you have a strong key management system.
For other uses, I'd consider the additional security too small to merit the additional pain.
Encryption is considered to be a lesser form of secret storage than message digest functions. In fact, storing an encrypted password is a clear violation of CWE-257.
But why not hash the username? When the login the application will have the plain text. Depending on your application, you might not need to display a list of users. this would be an added layer of security, as both hashes have to be broken before the attacker can login.
That being said, if you have a plain text list of every username it will be trivial to perform a dictionary attack against any recovered hash. Further more user names are not created to be difficult to guess, often times users choose goofy names of birds or silly games like chess so that they are easy to remember.

Safe to store unencrypted password into HTML5 client side database?

I am assuming the answer is that storing a password in a WEBSQL database on the client side, unencrypted is not safe, but i thought i would ask anyway, the reason I am asking, is I am trying to add a dropbox uploading tool to a web app, but i need the password in plain text in order to access the user's dropbox account, i surely could come up with some foobar way to hash the passwords client side, and unhash them when needed, but if I will be able to unhash them, anyone will be able to do so as well, does anyone have a work around if this is the case?
There is no such thing as 100% secure or safe. The goal of security is to be safe enough. You determine what is the risk, and what is the level of pain you are willing to go through and find the sweet spot.
If you have to get a plain text back from a cypher you have no choice but to use encryption not hashing. Of course you have to have the key somewhere, whether user entered or stored somewhere so the key is vulnerable.
Since this is on a client computer, it may be vulnerable to phishing attacks, social engineering attacks, trojan/keylogger/virus attacks, physical security risks, etc.
storing clear text is a bad idea, but other than that you have to decide what level of pain the users will suffer through.
PKI tokens are a good option if the cost is worth it. otherwise most languages have many various encryption algorithms that can be used effectively.
No, it's not safe to store plaintext passwords, period.
Assuming your users log into your web app with a password, why not use that password to encrypt their (salted) dropbox password? That's still less than satisfactory from a security standpoint, but it's better than nothing.
Using the words "foobar" and "dropbox" in the same paragraph is a clear signal that you're asking for trouble with a home-grown solution. You're asking your users to trust you with the security of their dropbox data, which means you're accepting an awful lot of liability. You're also asking your users to violate one of the fundamental laws of security: Never trust your security to a third party.
The best advice I can offer is to delegate all security-related tasks to an expert, and have that code audited by another expert.

Why would you ever want to store a plain-text or encrypted(not hashed) password in a database?

I've heard quite a few reasons for storing hashed passwords in a database. However, there are almost always options in authentications APIs to store passwords as plain text or encrypted.
Is there ever a reason you would want to store a password as plain text or encrypted in a database?
Note To be clear I know that storing non-hashed passwords are almost always bad.(as far as I know anyway) My question is why do most authentication APIs include options to store passwords as encrypted or plain text.
The only real reason I can think of is when the database belongs to a system that is itself targetting the real application. Like when you have programs that log into something for you (email clients, instant messaging clients etc.). All those have to store the password in a recoverable way to get access, because the target application won't decide between real user and user via a tool. Exactly at this point OAuth and alikes however are made to save the user's password.
One reason I can think of is to allow a password recovery option. There's no way to recover a password that the system doesn't know.
Of course the alternative is for the system to just reset the password to something new and send you the new password.
Maybe you're a hacker, and want to use or sell them?
Even if you are quite certain of the security of your database, your users' passwords are still accessible to all administrators.
It is vitally important to understand that password encryption will not protect your website, it can protect your passwords only.
If your website does not have sufficient protection, password encryption will not make it safe from cracking. If your system has been cracked, a hacker can inflict a irreparable damage to it and also gain an access to confidential information, including passwords database. But if you store this information encrypted, hackers practically cannot make use of it. Cracking an encrypted password takes a large amount of time and processing power, even on today's computers.
1) Most of Challenge-Response authentication protocols require server to know plaintext password. There are exceptions, but they are unpopular and hard to implement.
2) Storing passwords allow password recovery.
I have encountered the following argument a few times:
Storing plaintext passwords allows you to detect when a user changes their password to something close to an old password i.e. by incrementing a number, adding a '1', or by some other low-conditional-entropy updating method.
No one should take that argument as a good reason for storing plaintext passwords - it is misguided for several reasons.
Of course, you could store all passwords as plain text in your storage (e.g. database). But it's not recommended. If someone manages to hack your server and gets your data from the database he also got every password. Even just storing a password hashed with common methods like md5 is not quite save in this case. Because there are rainbow-tables (search google for this), to lookup passwords.
So I recommend to store salted passwords. I don't know why you ever would store your passwords as plain text. I wouldn't do it :)
The only 'good' reason I can think of is that the customer paying you to develop the app or your manager insists on it. I cant think of any technical reasons for it.
One reason could be to auto-reuse the password for another, external service.
If i configure my gmail account to retrieve my e-mail from other non-google e-mail provider i have to give google my password and google has to have this password in clear to get my mails into my gmail account.
That is obviously not the same password as for the primary service, but it is "of type password" anyway.

Why encrypt user passwords? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Why aren’t original passwords stored?
Why would one store encrypted user passwords in a database, if the password is the least valuable part of the data? It doesn't seem like it would affect external attacks; setting a limited number of login attempts per day per account would be effective. It doesn't seem like it would affect internal attacks; if someone can access the passwords, they've also got access to the more valuable data in the rest of the database.
Am I missing something here? Shouldn't the entire database be encrypted using user passwords as a key for the password encryption itself to be effective?
Combined his post below with his question:
Ok, I asked the question in a bad way. Let me rephrase this.
If someone breaks into this system, the fact that they have the user's passwords is one of the least of my concerns. I'll be encrypting passwords but in my humble opinion, the other data in the database is way more valuable. Assume that if an internal attacker has that data, they don't care about the passwords.
If nothing else in the database is encrypted and everything else in the database is what an attacker actually wants, did encrypting passwords actually solve anything?
Because, hashing passwords will protect it from attacks from inside the organization. This way people who have access to the database won't know the user's password.
People have a habit of using the same password over and over, and so if your database is accidentally compromised, your organization isn't the one that makes the user's other accounts comprised in other organizations. Now should people do this, no, but they do, and it's a lot easier to hash the passwords, than it is to explain to your customers why someone on the inside got a hold of the passwords and caused damage to several accounts in other systems not related to yours.
If you think that this reason is too exaggerated, you might want to know that it actually happened to Jeff Atwood, Stack Overflow creator. He described how the whole Stack Overflow was compromised in his blog post "I Just Logged In As You: How It Happened".
Edit:
To further answer you question, your other sensitive data should be encrypted as well. A lot of cyber attacts are inside jobs, and I hate to say it, but you have to be paranoid about who can see what information. Anything that you deem sensitive that you don't want people to know unless they are specifically authorized to see that data, should be encrypted in the database. You are right there are times when comparing what can be stolen the password isn't that much of a concern to you. The key is "to you". It is to other people, and should be protected along with the other sensitive data in the system.
What if you have a SQL injection vulnerability, someone steals your database, and uses the usernames, email addresses, and plaintext passwords you have stored to login directly to your users email accounts, bank accounts, etc. Do you really want to take on that liability? Conversely, do YOU really want to take on the responsibility of being able to see your users passwords in plaintext?
Reasons:
If someone (from inside or outside) will steal those passwords and publicly release them, you're doomed, you can instantly close your business.
Some people use the same password for many services. If some "attacker" can access e-mail address and password, the easiest way is to try if that password also works for that e-mail account.
You don't want this happen.
If you can access someone elses e-mail account, you can request sending forgotten password from victim's various services etc.
For internal attacks, if I can remember 5 username/password combos, then go to a public terminal and access those accounts, it's less likely someone will notice the attack than if I used a work machine to directly edit the database or pull out large amounts of data while at work.
And as everyone else pointed out, since we all have a hundred or more places online that all want different passwords... many, many people just use the same password over and over and over again. If the Williams Widget Company loses your name, login, and password, and your bank has the same login and password, and it's tracked back that the Widget Company was who lost your password... there's some muddling of liability there.
Because you don't want to fall into the design trap of sending unencrypted passwords, or thinking you can, since you won't have anything unencrypted to compare against, maybe.
Ok, I asked the question in a bad way. Let me rephrase this.
If someone breaks into this system, the fact that they have the user's passwords is one of the least of my concerns. I'll be encrypting passwords but in my humble opinion, the other data in the database is way more valuable. Assume that if an internal attacker has that data, they don't care about the passwords.
If nothing else in the database is encrypted and everything else in the database is what an attacker actually wants, did encrypting passwords actually solve anything?
Confidentiality, integrity, authenticity, privacy...
Remember your first security course, and try to count how many of theses are bypassed with your problem.
Four ? Well, it depends of a more specific view of the issue, but not far anyway :)
Also, you don't need to know the user password. Creating the the password hash on the client side is a good idea. Depending on your location there may be legal requirements when storing personal data and passwords.
Usually a hash of the password is stored in a database not the raw original text. This is to ensure extra security for the user credentials for external attacks on the system.
Comparison of hashes is done to verify the user credentials.
You may want to read more theory on why this is the approach followed inorder to understand it better. Wiki can be a start point for this.
When storing the password hash. Don't forget to salt it with something, so reverse lookup of the hash won't reveal the password. Yes, make it a long string before hashing.
I don't understand the last paragraph of the question. Sorry.

Resources