I'm looking for a stornger scheme than just password salting-and-hashing.
I want passwords file/DB that will not compromise:
Number of users
User names
User passwords
My basic idea is to hash and salt both the usernames and the passwords, and also to add 1000's of 'trap' entries into the database (for example, random user names ending with _xxxx with random passwords ending with _yyyy which won't be valid for real users).
Of course, when someone tries to log in, I'll have to check it against all lines in the database.
Is this scheme secure?
Notes:
The users are added manually. If a user has to be removed - the login names are stored in a safe.
I'm not sure if I can protect this scheme againt brute-force methods, but I think guessing both name and password is harder
Edit:
I'm protecting against a leak of the user/password file (as well as the application that read this file). As said, I need to protect the actual number of users, as well as their identities (or anything that may disclose their identities).
Number of users seems to be the hardest datapoint to protect. You can mask this by creating large numbers of fake users with nonsense names encrypted as you describe. These can serve double duty as the traps you describe, but then you need to be able to distinguish a trap from a real user which means it is possible for an attacker to do the same if they can compromise the trap-checker.
Who are you trying to secure it against?
Do you want to secure it against someone who compromises the DB, e.g by SQL injection, or a rogue sysadmin?
Do you want to secure it against someone who compromises the OS and gains access to the files that back the database tables?
The former can be mitigated by restricting access to the table to well-reviewed stored procedures, and tough DB access controls.
The latter can be mitigated by putting DB files on an encrypted partition, though this can slow down access and/or complicate startup.
Ironically, the larger the number of users, the more likely a brute force attacer is to stumble on a valid combination - and if they know that you have a lot of users with _xxxx or _yyyy in their usernames/passwords, that may give them a cryptographical advantage.
So, I would absolutely recommend that you give your bogus users no actual privileges, so that even a succesful guess yields no rights to the system.
Secondly, you might want to think about who you're protecting against, and how - it's widely accepted that a good hash/salt combination protects against most credible attacks; adding the username to that scheme just means you're protecting against attacks that don't currently exist.
On the other hand, you're doing nothing to protect against the far more common attack vector of "username on post-it note", "password = sex", etc.
The most common way to improve on "username/password" is to require users to have something physical.
Related
I have to create a simple security program that is about storing of passwords and the use of authentication mechanisms. I'm just not sure about what to choose from three selections and why it's better/worse over the others.
To me everyone can be seen secure, if it's done right, some are just easier and a lot faster to implement. The three possibilities I have are:
Storing passwords in a system file where the operating system will handle the confidentiality and integrity. (Not quite sure how this can be done, as I haven't storing anythings in a system file before)
Storing passwords in a public file in the program where passwords are hashed + salted (salt is uniqe for every password hash generated)
Storing passwords in a database and let the dbms handle the protection.
To me the best way if you should handle multiple clients signing up with a username/password, the best way is to use the database where also passwords a hashed + salted in it.
Can any of you make some comments how it can be done/pro/cons?
It is not so much about where to store the passwords, it is rather about how you store them.
If you can store hashes, because you only need to verify the passwords, then you should absolutely use slow password-hash functions like BCrypt, SCrypt, PBKDF2 or Argon2, most implementations add a unique salt on their own.
If you need to retrieve the plaintext passwords, because you must login into a 3rd party system, then you should take all possible measures to protect them (encrypting the db/file, require access privileges). The most safe solution is, when the user enters a master key whenever he wants to access the password storage, so the system itself is not able to decrypt them.
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.
I am building a project, which has a pretty basic login system. There will NO REGISTRATION system available, the users will be added manually. Also i protected the databases data input gates very well. So after all, do i still need to hash and even salt the users passwords?
And if your answer is yes, the next question is why?
Well, what would be the consequence of an intruder being able to impersonate another user? Weigh those consequences against the difficulty (which isn't very great) of adding hashing and salting.
One risk which you may want to consider is that if a user has the same password on multiple sites, then their security is only as safe as the weakest site. Even if you're manually assigning the passwords yourself (and not allowing the user to choose it) they may go on to use the same password in other sites.
Absolutely. It's one of the most important obligations to your users you have to honor - to treat their personal data very carefully.
If you generate the password for each user and do not let the user change the password, then you can make a case for not hashing them.
However:
You will have to explain to everyone that audits the system why you are not hashing the passwords.
You will have to have some way of proving that a system admin did not look at a user’s password then logon as the user.
A lot of programmers will think you don’t know what you are doing.
What if the system is changed at some point, or the code gets copied into another system.
I think of this like crossing a road.
You always look both ways even if the
green man says it is OK to cross.
(It is quicker to look both ways, then explain to any watching children etc why you don’t need to in this case)
In some jurisdictions/industries, storing login credentials in plain text could be a violation of data protection laws. If you're doing something like that in the US on a system that has even the slightest bit to do with medical or financial records, and you get audited, even if there's been no breach, you'll be lucky if the worst that happens is your clients and suppliers refuse to do business with you until your systems pass audit. There could be hefty fines as well. Even if your system doesn't work with sensitive data, if it's intended for use by people who routinely work with such data, the possibility that they may reuse passwords that are also used to access regulated data would at the very least make an auditor very nervous, and make their client extremely reluctant to work with you, even if you were technically in compliance.
Yes, because, e.g., people having access to the database can easily impersonate other users.
Yes, because your database is still there and a user system and its database are no more difficult to compromise without a registration form than with one.
Even if you protect your "database data input gates" very well, your database still isn't 100% attacker-proof. If someone still manages to slip through your defenses and sees everything in your database, and all the passwords are in plain text, your users' accounts are still compromised. By hashing them at least you're costing attackers more time, and at the same time protecting your users.
Yes, because there is always risk of compromising database. Remember, that many people uses the same password for many sites, IMs etc so you are making risk for not only information in your system.
People use their same password for more than just your site as well. If an attacker gets the passwords, there are more consequences than just your site. That user's email, bank accounts, etc may also be compromised. Do the diligent thing.
Why wouldn't you hash passwords? It protects you, your staff and your users and it costs almost nothing to implement. Users have a right to expect that your system administrators / DBAs / whoever cannot see their passwords and your administrators have a right not to be exposed to that information needlessly. In any internal/external technical security audit one of the first things the auditors will do is home in on any password columns in the database and determine whether they are hashed or not.
Also i protected the databases data input gates very well.
I bet every system designer/administrator for every compromised password file in the history of computing thought the same thing.
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.
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.