Storing Passwords Hashed in Database [closed] - security

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
Today I came up with a question about the web application conventions.
For the sake of security, if we store passwords of our users, most probably we are encrypting it (with MD5, SHA-1 etc.) and storing digested-hash in order to make them difficult or impossible to reverse.
Today there are many Rainbow Tables that are lookup tables of usual A-Za-z0-9 sequences up to 6 chars or widely used passwords. Let's say you are MD5-ing the user password once and storing the hash as password in database and someday hackers pwned your database and now they have many md5 hashes and e-mail addresses. Surely they'll look up passwords and when they got a preindexed match, they will try to login to that user's e-mail account.
Here this can be easily solved by digesting the message twice or simply reversing it. However I am wondering about what is the convention about this problem and how (as far as you know) enterprise applications or giants (Facebook, Google) solve this?

You use what is called a salt. Prepend some string that you make up before hashing. Prepend it also when you are checking the password. This is an application-wide string. This makes it much harder to look up via a rainbow table.
So if your salt is "kdi37s!!" save this in the db md5(kdi37s!!P#$$w3rd) and do the same when checking.

Use a little bit of salt and make a hash using sha1 or so.

Check out PBKDF2, it is one of the correct way to do it.

If you use an algorithm like BCrypt and salt (which uses the blowfish block cipher), it makes your db pretty safe against brute force attacks. Naturally, you want to require that your users have a reasonable amount of complexity in their password, if a user's password is a its not going to take long to guess it.
If an attacker gets a copy of your db, only being able to try 10 or so passwords a second will mean it will take a real long time to gain any passwords. If you are worried about Moore's law and would like to future proof this, you can specify a cost and make the algorithm even slower.
The trouble with a pure SHA/X or MD5 password hash is that by-design these algorithms are very fast, this makes it very sensitive to brute force attacks. Of course if you don't salt your hashes there are tons of rainbow tables that make cracking all the passwords in your db trivial.

Related

Store passwords safely but determine same passwords

I have legacy browser game which historicaly uses simple hashing function for password storage. I know that it' far from ideal. However time has proven that most of the cheaters (multiaccounts) use same password for all of fake accounts.
In update of my game I want to store passwords more safely. I already know, that passwords should by randomly salted, hashed by safe algorithms etc. That's all nice.
But is there any way, how to store passwords properly and determine that two (or more) users use same password? I don't want to know the password. I don't want to be able to search by password. I only need to tell, that suspect users A, B and C use same one.
Thanks.
If you store them correctly - no. This is one of the points of a proper password storage.
You could have very long passwords, beyond what is available on rainbow tables (not sure about the current state of the art, but it used to be 10 or 12 characters) and not salt them. In this case two passwords would have the same hash. This is a very bad idea (but a solution nevertheless) - if your passwords leak someone may be able to guess them indirectly (xkcd reference).
You may also look at homomorphic encryption, but this is in the realm of science fiction for now.
Well, if you use salt + hashing, you have all the salts as plain text. When a user enters a password, before storing/verifying it, you can hash it with all the salts available and see if you get the corresponding existing hash. :)
The obvious problem with this is that if you are doing it properly with bcrypt or pbkdf2 for hashing, this would be very slow - that's kind of the point in these functions.
I don't think there is any other way you can tell whether two passwords are the same - you need at least one of them plain text, which is only when the user enters it. And then you want to remove it from memory asap, which contradicts doing all these calculations with the plain text password in memory.
This will reduce the security of all passwords somewhat, since it leaks information about when two users have the same password. Even so, it is a workable trade-off and is straightforward to secure within that restriction.
The short answer is: use the same salt for all the passwords, but make that salt unique to your site.
Now the long answer:
First, to describe a standard and appropriate way to handle passwords. I'll get to the differences for you afterwards. (You may know all of this already, but it's worth restating.)
Start with a decent key-stretching algorithm, such as PBKDF2 (there are others, some even better, but PBKDF2 is ubiquitous and sufficient for most uses). Select a number of iterations depending on what is client-side environment is involved. For JavaScript, you'll want something like 1k-4k iterations. For languages with faster math, you can use 10k-100k.
The key stretcher will need a salt. I'll talk about the salt in a moment.
The client sends the password to the server. The server applies a fast hash (SHA-256 is nice) and compares that to the stored hash. (For setting the password, the server does the same thing; it accepts a PBKDF2 hash, applies SHA-256, and then stores it.)
All that is standard stuff. The question is the salt. The best salt is random, but no good for this. The second-best salt is built from service_id+user_id (i.e. use a unique identifier for the service and concatenate the username). Both of these make sure that every user's password hash is unique, even if their passwords are identical. But you don't want that.
So now finally to the core of your question. You want to use a per-service, but not per-user, static salt. So something like "com.example.mygreatapp" (obviously don't use that actual string; use a string based on your app). With a constant salt, all passwords on your service that are the same will stretch (PBKDF2) and hash (SHA256) to the same value and you can compare them without having any idea what the actual password is. But if your password database is stolen, attackers cannot compare the hashes in it to hashes in other sites' databases, even if they use the same algorithm (because they'll have a different salt).
The disadvantage of this scheme is exactly its goal: if two people on your site have the same password and an attacker steals your database and knows the password of one user, they know the password of the other user, too. That's the trade-off.

Password Management - Approach to Hash, Salt & Iteration

Have gone through several questions on this topic at SO, and am unable to find answers to this specific query. I've seen
Salting Your Password: Best Practices? and the excellent answer to Non-random salt for password hashes, which both have very helpful guidelines, but doesn't have a clear guideline on storage.
Is it advisable to have the hash, random salt and iteration count all in the same table? If not, what is a suggested approach?
I do understand that rainbow tables can't be made easily with random salts in place, even if we have them together. The question is because there are many simple extra deterrents that can go a long way. For example, have the salt in a different table (injections usually leach a table, not a DB) and the iteration count in a different tier (say, a constant in mid-tier).
It is the normal pattern to store the salt and iteration count together with the computed hash.
The salt is not a secret. A salt 'works' by being different for each computed hash. If the attacker knows the salt and iteration count, it does not help him in any way.
We have answered this question in various forms over on Security Stack Exchange.
Salting with the first 8 bits of the password - general agreement this isn't a good idea
Splitting a password - also not a benefit
These are similar in concept to your approach of holding all the information in the same table.
#Greg's comment is partially right - a determined attacker will be able to get all the data eventually, but the key here is around timing. A skilled attacker, given enough time and resources will be able to access your systems - the key is to making it difficult or noisy enough that you spot it in time.
From one of cryptographer Thomas Pornin's posts on our Security Stack Exchange blog:
Why passwords should be hashed - we hash passwords to prevent an attacker with read-only access from escalating to higher power levels. Password hashing will not make your Web site impervious to attacks; it will still be hacked. Password hashing is damage containment.

Is hash(site || password || salt) actually a bad idea? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
Suppose I were designing a web service with modest security requirements. For the most part, the threat model would be more about bored college students and less about anything you'd ever find in a spy novel. Would there be anything practically wrong with using the following password storage scheme?
salt || hash(site || password || salt)
where site is a unique identifier of my site, password is the user password, and salt is a user-specific random salt, and the hash is a general purpose cryptographic hash function like SHA-1, and || indicates concatenation.
I'm aware of certain issues that come up with this scheme.
The hash is (designed to be) fast to evaluate, and one iteration would leave particular weak passwords guessable.
Concatenation alone might cause "puns" in the overall input to the hash.
Now, there are certain security professionals on the Internet who would have me believe that, if this is my idea of a good enough password hashing scheme, I could not possibly deserve employment and desperately need to return to school. They point out that there are well-known password hashing schemes with far better properties from a security perspective. They demand that I switch to something better.
But really, should I? I have a bit of a counter argument here.
This is probably not going to be the weakest link in my service. Someone truly determined to break in has plenty of other avenues, and I should prioritize my time to secure the weaker ones.
Cost-benefit is already against the attacker's favor if my site has little intrinsic value. How much of a practical concern is it that a large cluster/botnet could recover a weak password in a day/week? Surely it has more valuable things to be doing that day/week.
Compromised accounts are more likely to happen because of trojans, keyloggers, social engineering attacks, what have you. Technology isn't the limiting factor in this security.
The more complex my scheme is, the more difficult it might be to move/expand to another platform. If I used bcrypt (hypothetically), I'd potentially have to write a bcrypt wrapper and incorporate that.
I really like this scheme. It's really simple. The implementation is hard to get wrong. And I would argue, for all intents and purposes with regard to an average site, it should be fine. Asking me to put in a better hashing scheme almost sounds like asking me to install a bigger lock on a door that is already very vulnerable to chainsaws.
If I would be doing something wrong here, I would very appreciate that someone point it out, especially in terms of practical and real-world-applicable concerns.
Thanks.
See What is the point of salt and hashing if database is accessible?
Salts prevent (some) rainbow table attack sbut they they don't prevent dictionary or brute force attacks.
Use Scrypt or bcrypt instead, where Scrypt is much stronger but both uses a Proof of Work system to make it much harder to crack a password. See the OWASP Password Storage Cheat Sheet
From a pure hashing perspective, unless I'm reading your question wrong, you're proposing creating a hash of the password concatenated with a user specific random salt which is the usual approach. Any additional data involved in the concatenation won't make a whole lot of difference if you've already got a cryptographically random strong salt of sufficient length.
Then there's the old argument about which hashing algorithm is the most secure and of course bcrypt will trumps the likes of SHA - and particularly MD5 - due to it's adaptive native and ability to increase the hashing process duration to ward off brute force attacks.
However, you could pragmatically argue that for most general purpose website cases, SHA1 and above would be sufficient. When you look at the breaches we've seen in recent times, password disclosure is usually happening when they're either stored in plain text (obviously very vulnerable) or hashed without a salt (easily vulnerable to rainbow tables). Sure, the SHA derivatives will be faster to work through (particularly if it's a single hash), but in combination with a cryptographically random salt it's not a small task.
Case in point: the ASP.NET membership provider from Microsoft uses SHA1 and is very extensively used. There is no native bcrypt support (although third party libraries are available), which probably should tell you something about how Microsoft views the issue.
Finally, there's also the issue of password strength. Setting a long, strong requirement will obviously contribute to the strength of the hash against many brute force techniques. Of course there's the usability trade-off, but that's another issue.

Which password hash function should I use?

I am looking for a password hash function that can stay with me for years. Picking the wrong one can be fatal, as it is impossible to upgrade the existing hashes without having the users log in.
It is often suggested to use bcrypt or sha256-crypt from glibc. These use
key stretching,
but I do not like the fact that I am unable to extend the stretching later on.
One should be able to keep up with Moore's law.
Right now, I am considering the simple algorithm from the Wikipedia link, with SHA-256 for the hash function. That one allows me to just keep adding iterations as I see fit.
However, that algorithm is not a standard. It is therefore unlikely that I will ever be able to use the password hash with LDAP, htaccess, and so on.
Is there a better option available?
You should use SHA1 for password hashing. However, more than algorithm, you should also consider adding salt to passwords. Ideally a random salt should be created for each password and stored along with password.
This is to defeat rainbow tables.
Great discussion on this : Non-random salt for password hashes
I may be coming at this from another angle, but if you are saying that you may have users who will not log in for long periods of time then that presents a big risk. The longer you allow a user to stick with the same password, the greater the risk of bruteforce from an attacker who manages to grab your password hash file somehow. Don't rely on security preventing that ever happening...
Hash functions don't go out of date that rapidly, so I would imagine you should be fine reviewing this annually, as hopefully you will have your users change passwords more often than that.
It all depends on your exact requirements, obviously, but have a think about it.
In general bcrypt or sha256 can suit the requirement nicely.
Update: You could think about popping this query across to security.stackexchange.com, as it is a security management question.

Salts and Passwords - prefix or postfix

This is a question about salting phrases that need to be hashed.
I was wondering if it more secure to prefix the salt to a phrase or postfix it?
salt + phrase or
phrase + salt
My question comes from this comment on this post on MD5s. I am not sure I understand the reasoning behind the author's comment.
Whether the salt is appended to the front or the back makes no difference.
The following factors will affect security though
Is your salt private (if so how private is it?). The more private the better. This means that if you can avoid storing your salt in your db you can make your system safe against brute force attacks even if your db is compromised.
Is your salt random per value salted? This helps defend against rainbow table attacks if say your db is compromised and your salt is stored in the db. Note: if passwords being stored are long enough they can be immune to brute force attacks.
Is your salt long enough? The longer your salt the more secure you are.
When someone has a question about the use of salts I fear it is because they are busy (re)inventing things they really shouldn't be in the first place. Based on the question my recommendation is to use an HMAC.
It doesn't matter when you digest the salt: prefix, postfix, infix all produce different hashes, but achieve the same purpose of defeating rainbow tables or other pre-hashed dictionary attacks.
I think that the comment has to do specifically with a vulnerability in MD5, not hashing in general. I don't understand the details, but it has to do with finding two prefixes that produce the same hash.
unlike what others said, it does matter! and as #einstein if you care use HMAC.
why prefix is bad, because one can calculate the intermediate state of the checksum up to the given fixed salt prefix. then start calculating the rest in parallel. In summary phrase+salt is more secure than salt+phrase, but HMAC(salt, phrase) is even better.
related reading
Technically it doesn't matter, so long as the salt is unique and not easily guessable. Just don't make the mistake of storing the salt, like I did.
The purpose of "salting" a string is to scramble it in a way a bit more personal and unique than an MD5 hash will do. There's no right or wrong way to do it, just so long as you're the only one that knows how it works. It will achieve the result either way, which is to make the MD5 hashes generated not correspond with a rainbow table for easy cracking of passwords.

Resources