Advanced Hashing

Discussions of secure PHP coding. Security in software is important, so don't be afraid to ask. And when answering: be anal. Nitpick. No security vulnerability is too small.

Moderator: General Moderators

User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Re: Advanced Hashing

Post by kaisellgren »

Mordred wrote:Assume nothing, analyze all scenarios.
If you do not like the word choice, just replace "assuming that" with "if". The condition is needed, because there are two situations.

A) The salts are not strong or do not exist = approach 2 is better.
B) The salts are strong and do exist = approach 1 is better.

The word "salts" refers to "database salt" and to "file system salt". In case the file system salt is missing, then the second approach is better.

The best approach is to use a strong hashing function, a strong key and doing nothing else.
User avatar
Mordred
DevNet Resident
Posts: 1579
Joined: Sun Sep 03, 2006 5:19 am
Location: Sofia, Bulgaria

Re: Advanced Hashing

Post by Mordred »

@kai:
1. We're talking only of the security properties, not performance (i.e. if you somehow imply faster=better, it doesn't apply since we discuss security only)
2. Salts are explicitly given in the scheme, they are not missing.

Reconsider your "if" condition and define "better" when you use it (Why "better" and "better" in what way exactly?)

@Apollo:
You also add assumptions to the scenario, while the task is to explore the possibilities and see how both schemes compare.

--------

Not entirely related to this last point, but if I find the time I'll setup some software using different hashing schemes with practical attacks against each. I've made some research on how people implement this and I've attacked real databases with a custom-made tool and I think people should be more aware of how much the attacker can achieve with some simple software and WITHOUT needing any cryptological breakthroughs or thousands of processors.
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Re: Advanced Hashing

Post by kaisellgren »

Mordred wrote:1. We're talking only of the security properties, not performance
I was not only talking about performance. Read my previous posts.
Mordred wrote:2. Salts are explicitly given in the scheme, they are not missing.
You forgot one thing - the strength of them was not explicitly defined.
Mordred wrote:Reconsider your "if" condition and define "better" when you use it (Why "better" and "better" in what way exactly?)
You can not omit the word "if". Depending on the strength of the salts, the answer may vary.

Consider this scenario where salts are weak:

Code: Select all

hash('pass'.''.'');
hash(hash('pass'.''.''));
The database salt was "" (empty) and the file system salt was "" (empty). They are as weak as possible (=useless). In this case, the approach 2 is definitely the way to go, because it strengthens the preimage.

Now, think about this:

Code: Select all

hash('pass'.$a.$b);
hash(hash('pass'.$a.$b));
Where $a is 1024-bits taken from /dev/random and the same applies to $b.

The question is, which one is better? In performance wise of course the first one, but when we are talking about security, it is the first approach. It makes no sense to strengthen something that is strong. Yes, you may now argue and tell me that the stronger the protection the stronger the safety. That is not, unfortunately, that simple. If you really think that way, then you should ask for one million characters long binary passwords from your users. If you do it, then your users will not remember their passwords and they will jot them down into text files on their desktop and whatever - then they are more likely to be exposed to attackers, which leads us into the situation where the shorter passwords would have been safer in overall. I know that certain things can be strengthened infinitely, but that defeats many principles of security such as Keep It Simple.

So, did you want me to define the word "better"? When I refer to it, I am talking about the overall security design.

Again, there is no clear line. The stronger the preimage, the less chances that the second approach is "better" in terms of security.

Security is never straightforward, when we are developing our application, we must consider the overall security design of it.
User avatar
Mordred
DevNet Resident
Posts: 1579
Joined: Sun Sep 03, 2006 5:19 am
Location: Sofia, Bulgaria

Re: Advanced Hashing

Post by Mordred »

No, you misread me, I'll try to rephrase:

Is there a situation where variant 1 provides better security than variant 2? What are the conditions / parameters that make it so?
Is there a situation where variant 2 provides better security than variant 1? What are the conditions / parameters that make it so?
Is variant 1 exactly as secure as variant 2 in all possible circumstances? (In that case, security being equal, we may start discussing a secondary property such as performance or something else)

Of course you need the conditional - the whole point is to find the condition.
I do not disagree with anything you say on the topic lately, it's just that you're missing what I mean by my question, that's why I rephrase. I want you (= all participants in the discussion) to reach a definite answer on the comparative security of both variants. I believe such one exists. I also believe it proves a point of mine, that's why I'm so insistent ;)

I also accept your point on empty salt = salt with zero strength, just remember that there are situations than the extremes ;)
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: Advanced Hashing

Post by josh »

Without rigorously studying the proofs there's no way to even say a salt wouldn't increase the probability of collisions. So called "pepper" would be better then salts.
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Re: Advanced Hashing

Post by kaisellgren »

Mordred wrote:Is there a situation where variant 1 provides better security than variant 2? What are the conditions / parameters that make it so?
Is there a situation where variant 2 provides better security than variant 1? What are the conditions / parameters that make it so?
The questions you gave us are kind of multidimensional. Generally speaking, there are two things: defenses and protections. They both are different. A defense prevents something bad from happening while a protection decreases the likelihood of something bad from happening. The word "security" holds those two words within, so it would be clearer to ask "Is there a situation where ... provides better protection". While there is nothing wrong with the word "security", it includes the "defense" -part, which is kind of irrelevant in this situation unless that is what you explicitly wanted to ask for.

These questions you asked are hard to answer. I am not even sure what you wanted to exactly ask (I am sorry :lol:). Are we looking for maximal protection or maximal security? Theoretically speaking, we can always make our protections stronger if we keep using stronger preimages. Instead of using a salt of 64-bits of strength, we use one with 65-bits of strength. Now we could use 66-bits to further increase our protection. And so forth... we can continue this again and again endlessly (theoretically). In practise, there are limits, of course. How much can your hardware handle (or the software you are using). I have no answer to that.

Further more, there is a dilemma. Defenses are good guys, they defend us and increase the security as a whole. We always aim to add defenses into our application (Defense in Depth). Protections, however, are witches. When you increase protection of some part of your code, most likely you are decreasing the security of other parts of your whole security design. For instance, the password situation that I described earlier, belongs to this category. Typically a website asks for a username and a password. To make our protection stronger, we could ask for 100 different login values that construct the final login equation. This, however, will reduce the overall security design in many ways, namely, the users start being logged in, they start to save their form field values, they start to put the details into files on the desktop, and so forth. The likelihood of programming level mistakes also increases.

So, what do we aim for? Maximal security? Or maximal protection of the hashed passwords?

Let 's think about a situation where we are doing something like:

Code: Select all

$xss_safe = htmlspecialchars($data,ENT_QUOTES);
Let's also forget XSS for now since it's irrelevant to our problem. Now, what if the function we called fails and it returns the original string? Obviously we are screwed. Look at this code:

Code: Select all

$xss_safe = htmlspecialchars($data,ENT_QUOTES);
if (strlen($xss_safe) == strlen($data))
 $xss_safe = htmlspecialchars($data,ENT_QUOTES);
What that code does is that it checks if the size of the data has changed. If it has not, call the function again. This adds protection into our application, but is silly and useless. The coder has to trust its code. If you can not trust something, do not use it. That code does increase the protection level of that part of the program, but the amount of protection it adds is minimal. It is more likely to win one million dollars in a lottery than to gain some use of this implementation. At least nearly as likely.

This is the reason why security is not that simple. Security is complex. You have to make decisions. How much strength do you want? The more strength our hashed passwords have, the greater the protection of our hashes, but this does not apply to defenses. It applies to protections.

What I have been talking about is the overall security. Therefore,
Mordred wrote:Is there a situation where variant 1 provides better security than variant 2? What are the conditions / parameters that make it so?
Yes variant 1 provides better security in a condition where the protection level of our hashed password is not weak. Not weak means that it is strong. Being strong implies that it is practically not breakable at the moment. It may be broken later, which is the reason why it is important to have dynamic hash switching system as well as being able to accept longer salts, etc. Our hash is supposed to be safe, not secure. Safety is the condition of being safe while security is the condition of being secure. Our hash is safe at the moment, but will be eventually obsolete and therefore it can not be secure. For this reason, neither of these variants can be secure, but you can still use the word "security" in that sentence, because you said "better security". It is a comparative.
Mordred wrote:Is there a situation where variant 2 provides better security than variant 1? What are the conditions / parameters that make it so?
Yes variant 2 can provide greater security than variant 1 in a condition where the hash value is weak, which means the hash value is not strong, which leads us into the situation that our protection of hashed passwords is not strong. This means, that the security will neither be great, but with variant 2, the multinous hashing will add more strength into our application, so the protection level is greater than with variant 1. The protection we add is higher than any possible protection we might lose somewhere else in our overall security design.

But if we are talking about protection, then:
Mordred wrote:Is there a situation where variant 1 provides better security than variant 2? What are the conditions / parameters that make it so?
Yes in a condition where the preimage is enough strong. If you are asking me to determine the "enough"-level, then forget it. I will not try to throw exact values. There is a line somewhere, which no one can decide for general use. It does not only depend on the strength of the preimage, but also on the underlying hash function and the overall security design of your application.
Mordred wrote:Is there a situation where variant 2 provides better security than variant 1? What are the conditions / parameters that make it so?
Yes and the condition is that the strength of the preimage must be enough low so that the entropy lost in addition to multihash key strengthening of multinuous hashing is covered by it. It is again, impossible to give exact values not just because of practically very hard mathematical expressions, but also because it depends on the hash function and on the salt.

Mordred wrote:Is variant 1 exactly as secure as variant 2 in all possible circumstances? (In that case, security being equal, we may start discussing a secondary property such as performance or something else)
Again, are we talking about security or protections? In case of protections, there might be a situation where both are equally as strength and in case of security, there might be a situation where both equally add up in the overall security (but that would require us to implement some sort of quality determining system). When should we consider performance over extra security? That comes far earlier than at the point where these two variants are as equal in strength. For security, that point does not come as soon as for strength, but in both cases it is up to the coder to draw the line. It is practically impossible in many cases to predict how safe our hash function is, for instance. It makes little sense to find the perfect situation where both variants are as equal in strength (or in security - in which case we need to define how we determine the security level).

In case someone does not understand the difference between safe and secure, let me explain that:

Safe: Not exposed to and is protected from danger or risk.
Secure: Is certain to remain safe and unharmed.
Safety: The condition of being safe.
Security: The condition of being secure.

While these two words seem similar, they are not. The word “safe” is used often in cases when we are talking about human lives, health and other things in general. The word “secure”, however, is more used in cases when we are talking about criminals or crimes. Imagine a weather storm outside your home. Staying at home keeps you safe from getting wet. After the weather storm has faded out and the sun is shining, using sunscreen will make sure your skin is safe. Now, think about banks. They keep your money inside a safe. Why is it called “a safe” and not “a secure”? This is because the safe does not just protect from criminals, but also from environmental hazards and so on

In web environments, using the word “secure” is more likely the right word choice, because we are trying to protect from attackers who are more or less criminals. Another difference between the two is that being safe does not mean that it remains safe. It only describes the current situation. For instance, the sunscreen discussed earlier keeps you safe, for a while. After certain amount of time, it will not help you anymore, because of the durability of sunscreens. More over, claiming that a system is secure means that it is secure at the very moment and will stay like that. A computer hard drive may crash at any moment. Therefore, claiming that a hard drive is secure is bollocks.

Right now I feel a bit tired, I'll probably answer next time tomorrow.
Post Reply