Its being deployed as dual stack, and where folks have IPv6 only I understand that the providers have 6to4 translation devices.
You are mixing up terminology. 6to4 is a tunnelling method. It requires both ends of the connection to talk IPv6, but the network between them can be IPv4 only. It works great as long as both ends are using 6to4. Unfortunately we don't have enough IPv4 addresses to deploy IPv6 that way, and 6to4 and native IPv6 don't play well together. The problem is that in order for 6to4 and native IPv6 talking together, you rely on third party relays. With two different relays being used for traffic in the two directions, and many of the public relays not being very reliable, you end up with flaky connectivity. I actually developed a new method for tunnelling IPv6 over IPv4, where I managed to get the best of both worlds.
But I don't think what you have in mind is tunnelling. There is this thing called NAT64+DNS64. When a client is using IPv6 only sends an AAAA query to a DNS server with DNS64 support, the DNS server can look up the IPv4 address and translate it into an IPv6 address. Then the NAT64 unit can translate all the packets to put a number of IPv6 only clients behind a single IPv4 address. That way you can run the access network as IPv6 only and still talk to IPv4 only servers. But I don't know of any protocol who works better through NAT64 than it would through a carrier grade NAT44 solution. Running dual stack on the access network with RFC1918 addresses is most likely going to be better for the users than NAT64.
But neither of those NAT methods work for anything other than a pure client-server model with the server on a public IPv4 address. Any protocol that does not fit directly into that model will break, and the best solution for that is to deploy IPv6 to all the parties that need to communicate.
an IPv6-only subscriber using a device with a hybrid dual-stack can access an IPv4 address by specifying the applicable IPv6 address.
That will not work. The IPv4 only node will need to communicate with some IPv4 address, and there is none to be used for that purpose. If you read the other replies to your post, you will see that they seem to disagree with each other. That is because there are actually two different formats. There is the deprecated::/96 prefix, and there is the currently used::ffff:0:0/96 prefix. The later is used such that applications can use a single socket to talk both IPv4 and IPv6. It is entirely an API feature. Those addresses are never send on the wire. The actual traffic on the wire is IPv4 from one end to the other.
There are NAT solutions which will help a bit. There is NAT64+DNS64 if your LAN is IPv6 and backbone is IPv4. And I have developed a system for a LAN running IPv4 connecting to a backbone running IPv6.
Once IPv4 runs out of addresses, the need for dual stack will be gone.
In the ideal world, that would be true. In the real world, IPv4 addresses have run out in some parts of the world already. And yet more than 95% of the Internet is still IPv4 only.
True. But dual stack would have been the simplest way to transition from IPv4 to IPv6, as long as it was done before IPv4 addresses ran out, and all sorts of workarounds got in the way. The fact that dual stack is more complicated than running just one protocol by itself is of course a contributing factor to people hesitating with deploying IPv6. But you cannot blame that on the design of the IPv6 protocol. Nobody have provided a serious suggestion for a better design.
I see living with a dual-stack environment for a while. It will not be pretty.
We could have had dual stack for a while and then dropped IPv4 support before the IPv4 addresses ran out. That would not have been as ugly, as what we can expect to see now. There is one good thing to say about dual stack though. If you mess up while changing network configuration remotely, you have a fallback, since misconfigured IPv4 can be fixed by logging in over IPv6 and vice versa.
As a consumer you do not need IPv6 unless your provider does not have IPv4 addresses to assign to you
You do if you need to communicate with somebody else who does not have an IPv4 address. And since ISPs have been handing out fever IPv4 addresses than the number of devices to be connected for the last 15 years or so, there is actually already a lot of devices, which do not have IPv4 addresses. Unfortunately, most of those don't have IPv6 addresses either.
IPv6 is too complex, which is what has hampered its slow adoption from the beginning.
IPv6 is simpler than IPv4.
Instead of simple address space extension, the brains behind it decided to add all sorts of fun features to it that just aren't necessary, thus leading to people not wanting to put the effort in to figure it out.
That's just a lame excuse. There are some new features, but those are mainly important to the endpoints. For routers in between, the job they need to do became simpler. And it is the network, which has been lacking, not the endpoints. The excuse that it is too complicated has mainly been used by those who didn't need to deal with the complexity.
Since those features have died off, it's getting less terrible, but now it's a moving target.
Name one change that affected a network provider, who just has to move packets between two endpoints.
KISS would have gotten us to IPv6 5 years ago.
No. There were only two approaches that could have speeded it up. Top down regulation or customer demand. But both of those were in the hands of people who won't understand the problem until they can no longer get online. Actually, there is one other thing that could have speeded it up. If we had never gotten any sort of NAT for IPv4 in the first place, then the transition would have gone faster.
Unless you are very careful about how you define slowness, I think collision resistance (or something like it) might actually be important.
I think the proper definition would have to include: "An adversary who has spent x% of the resources required to compute the output has at most x% probability of guessing the correct output." In reality the actual probability as function of the time spent isn't going to grow linear, but more likely as a convex function. The definition just requires a linear upper bound, which in some cases could be much higher than the actual probability.
I met somebody about a year or two ago who told me that routing 10-gigabit traffic today is kind of like sexing newborn chickens. At that speed, you aren't analyzing headers... you're making single-bit snap judgments on a slightly-blurry bitstream, and hoping it wasn't noise that sent a datagram meant for someone in Ohio to Shanghai instead. Or more precisely, you have a few circuits sniffing the blur in parallel, voting on what they think its destination is likely to be, and majority rule deciding where it goes next.
Then how come I never see the number of hops between two endpoints vary as packets occasionally take a longer path than they should have? When switching and routing, you need to be able to buffer packets. (If output port is idle and running at the same speed as the input port, packets can be forwarded without buffering, but that's rarely the case on the entire path). When you need to be able to store the packet, then you can spend more time finding the correct destination. If you know the destination by the time half the packet is received, then it is far better to store and forward than to send it down the wrong path.
Ethernet has a minimum packet size, which is longer than the header. But not all equipment can handle packets at wire speed if they are all of minimum size. There is a reason why there is a desire to increase the maximum packet size. If 500 bytes can fly by before you know where to send the packet, then you buffer those bytes, and that may mean packets have to be larger than 500 bytes on average in order to achieve wire speed. Though the minimum packet size does help a little bit here, the reason there is a minimum size is actually something different. Originally the minimum size was in the standard to ensure that packets were long enough to reach from one end of the cable to the other.
Are you certain we are not a simulation of a system in a 83 dimensional universe made by beings who oversimplified their universe simulation?
I can say with 90% certainty that you got the number of dimensions wrong. If you left out the number of dimensions, your theory would sound plausible. Look at the quantummechanical duality between particles and waveforms. It looks like a clever hack to simulate continuous physical phenomena with a quantized representation in the simulation. Can anybody come up with a more plausible explanation for why that duality exists? I am just hoping I'll be the one to discover the vulnerability that will allow me to break out of the sandbox. It would give me access to all knowledge in the universe and unlimited computational power.
A court order in Brazil gave an order, and google was in contempt, don't like it? change the law or don't operate there.
I doubt that he could have taken the video down in the first place. Google has a five digit number of employees. They do not all have access to remove videos from YouTube. I would have checked what the article had to say on that matter, but the link is broken.
If the goal is to pick the higher safety rate, and there is a 99% confidence that the automatic car has the higher safety rate, wouldn't that be better than only being 95% confident that the automatic car has the higher safety rate?
Nobody is saying that 95% is better than 99%. If there is 95% certainty that automatic cars are safer, would you rather be using manual or automatic cars? Is anybody going to say that they would rather use a manual car because there is only 95% certainty, that the automatic car is safer?
As for the 99% we'll get there over time. But even before there is enough data to reach the 99% you still need to make decisions on what to do until then.
I guess you are right, but in that case I'd argue that they have been answering the wrong question. What we really want to know is whether automatic cars or manual cars are safer. And the answer they can provide says, we don't know.
Faulty cars can cause accidents, even if they are driven manually. If you could save 10 out of every 100 people killed in traffic, wouldn't you want to do it? Or do you really rather want a 100 people killed, where you can put the blame on some person, than have 90 people killed where you cannot find a person to blame?
Or put differently, if you had 90 people getting killed in accidents, would you really want to sacrifice another 10 lives just so you can put the blame for the first 90 on somebody?
My point is, the ability to put the blame on somebody is not important. What is important is the total amount of accidents.
Well, if you're going to err, this is one of those times when you want to err on the side of caution.
But what does side of caution even mean in this case? What if you instead of 99% confidence only had 80% confidence? It would mean that there is at least 80% chance that an automatic car is safer, so in other words is there at most 20% chance that a manual car is safer. How does the principle to err on the side of caution lead you to choose the approach, which has less than 20% chance of being the safest of the two?
Or you drop support for the old pepper and mass-expire all the passwords
Supporting two or supporting an arbitrary number is about the same amount of work. If you only support one at any given time, you are going to have chaos when you change it and every single user password stops working. And you are going to have problems as you gradually roll out the change, as anybody who have worked with production systems know you should do.
Besides, if you immediately expire all the passwords on a leak of the pepper value, there wasn't any point in using that value in the first place.
require users to use a password reset mechanism (equivalent to the "lost password" functionality you should have)
For those users who have chosen a strong password in the first place, there is much higher risk that somebody takes over their account due to an insecurity in the password reset procedure than there is of the password hash being broken. Even if the password is hashed just one time using MD5 and not using any salt or pepper, a strong password is still secure.
Want to prove me wrong on the MD5 claim? I generated a strong password, MD5 hash of that password is ccd8af43e22f5662cb3d021e222da920, MD5 hash of password followed by newline is 9f0dc9d398dbc503d816fd2ba4b4d1ee, MD5 hash of password followed by carriage return and newline is c256fe8a5c59e7c50a44bd1ee94d6e0f. I don't think anybody will ever invert any of those three MD5 hashes.
Sure you could, it just wouldn't help if I can invert at least one of them.
You are assuming that the slow function is used in an insecure high level design. The way cryptographic systems are designed is to take primitives where you make assumptions about the security properties of the primitives, then you put those primitives together in a high level construction, where you prove that it is secure. The proof relies on the security properties of the low level primitives.
When done this way, you cannot break the high level system. You can only break the primitives. If you do break one of the primitives, the high level system would become insecure until you replace the broken primitive with another primitive of the same class, but not broken yet. For example many constructions use cryptographic hash functions. If you have such a system using MD5, then it is insecure. But if you were to replace MD5 with SHA512, then it would be secure again.
At no point did I say the slow function was supposed to difficult to invert. If you design a high level protocol with the assumption that the slow function is difficult to invert, you are at fault for designing the high level protocol incorrectly. This is just as bad as assuming that a cryptographic hash function is slow to compute, which is not one of the accepted assumptions about a cryptographic hash function.
I did point out that I expect the slow function to be combined with a cryptographic hash function. In fact the only sensible thing you can do with the output of a slow function as I described it is to pass it through a cryptographic hash function (perhaps combining with other data, which could be as part of an HMAC construction). The point is that each of the primitives serves a well defined purpose, and you can reason about them independently.
Unless you are very careful about how you define slowness, I think collision resistance (or something like it) might actually be important. For example, suppose 90% of all inputs result in the same output
That is a valid point. And that is something that the formal definition would need to take into account. But to address that point it is sufficient that the probability of two inputs producing the same output is small, it does not need to be negligible.
For example if the probability that two random inputs produce the same output is 10^-10, then it is impractical to rely on collisions if you want to break passwords. It would be much more efficient to simply compute the slow function than to test enough passwords to find the one where the 10^-10 chance of producing the right output comes out in your favour. So given today's computational power a 10^-10 probability is small enough. On the other hand a hash function with 10^-10 probability of collision between any random pair of inputs is absolutely not collision resistant. You only need to evaluate such a hash function on roughly 10^5 inputs to find a collision. Even if each input took five seconds to hash, it would only take a week to hash enough inputs to find a collision.
So, the requirement that would be needed would be much weaker than collision resistance. Moreover the probability of two inputs producing the same output is something that has been considered for non-cryptographic hash functions in the past. And there are even constructions with formal proofs of such probabilities. And for those constructions I am not talking about something that relies on assumptions about the security of some cryptographic primitives. For example if you want to produce message-authentication-codes using a shared secret, it can be done provably secure. And a large part of the construction comes from hash functions with a known probability of collisions.
That little detour was just to point out some of the work in that area, which could be relied upon. Now getting back to the slow functions, I should elaborate on something I said earlier.
Properties that I would not require a slow function to have includes collision resistance and fixed size outputs.
The part about not requiring fixed size outputs is a bit more important than it may seem from what I wrote. If you look at input and output sizes of hash functions and PRNGs you'll find a difference. Whether you are designing a cryptographic hash function or a PRNG, you want the output to be indistinguishable from random. The most important difference between those kinds of primitives is that you use a hash function when you want the output to be small and a PRNG when you want the output to be larger than the input.
A hash function always produce outputs of the same size, which in most applications is smaller than the input, hence collisions are guaranteed to exist, but may be hard to find. A PRNG always produce a output that is larger than the input.
The slow functions I suggest do not require the output to be nearly as random looking as that of a hash function or a PRNG. They also don't have to produce outputs of some specific size, the output can be smaller or larger than the input. But in order to satisfy some of the other requirements it is a good idea to produce a large output. It is easy to avoid collisions if the output is larger than the input. If you design a slow function from the start to satisfy the definition I suggest, it may as well append every single intermediate calculation along the way to the output. As such a slow function is being evaluated on a tiny password, the output may very well be multiple MB in size.
That is another reason why I would imagine the slow function being combined with a cryptographic hash. Any design involving a slow function is almost certainly going to pass the output through a cryptographic hash with the usual collision resistance requirement.
I think one problem with existing ways to create slow hashes by composing them out of fast ones is that they decrease the entropy.
The main point with my proposal to split the hashing and slowness into separate is that each of them have a much smaller set of requirements, and thus a much smaller set of possible vulnerabilities. The specific problem you mention is not considered a major threat, but my proposal still protects against it.
In my suggested model, the slow function is where you could choose to use an iterated hash function. But there is no requirement that the slow function preserves all of the entropy. If the slow function was to lose a bit of entropy, that would not be a major problem. If it lose so much entropy, that the output is completely predictable, then it is a real problem. But you'd be able to demonstrate the entropy leak by using the birthday paradox to find an example collision a long time before the lost entropy became a real problem.
The point of my construction is, that you can still argue about the security of the system even if the security of the slow function completely breaks down. The worst case for the slow function would be if the output was constant (if every input results in the same output, you just need to compute it once). But even in that case, you can make a full system, which requires one invocation of the cryptographic hash for every password that is attempted.
Protecting against the entropy loss in iterated hashing is by now means a new idea. What I think is a new idea is that of splitting the slow part and the hashing into separate primitives and providing two proofs for the security of the system with a broken slow function and with an unbroken slow function.
a capable attacker can still generate a rainbow table for this particular website
No need for the additional overhead of using a rainbow table for this. Just apply a generic brute force dictionary attack without using rainbow tables. It will be much faster, if there is just a single leak.
The rainbow table only helps if it can be precomputed, which you can only do if that salt is leaked before the database. If a site repeatedly have leaks of their password database, and the salt remains unchanged between leaks, then for any subsequent leak the salt is previously known, and a rainbow table can be used. But after the second leak the only users still using the site will be those who don't care about security anyway.
salts should be uniquerandom for every user
That is correct, and it should change whenever the user update their password. You can combine the two and have one value, which is constant for the site and one that is unique for every user. It is the salt, which is unique for every user, that provides the majority of the security. The other value, which is fixed for all users on the site is sometimes referred to as pepper. If the pepper value is leaked, it provides no additional security, but you still have the security provided by the unique salt values. But if the pepper value is not leaked, then nobody can even start brute forcing the password hashes or compute a rainbow table, even if the entire password database is leaked. That gives more time to get passwords changed, if you are lucky and only the password database is leaked and not the pepper.
For example if the pepper value is a hardcoded value in the source code for the site, then it doesn't have to be present anywhere in the password database. Some attacks cause a leak of only one of the two, and in those cases you have more time to get passwords changed. If they are leaked simultaneously, you are left with only the security of the salt, which is what you'd have, if you weren't using pepper in the first place.
If either the pepper or the database is leaked, you have to change the pepper value (as soon as you have closed the hole, which allowed the leak in the first place). But until all passwords have been changed, you still have to support the old pepper value. That means to properly use this, you need to have a hardcoded array of pepper values in the application, and store an array index in the user entry in the password database.
The use of such a pepper value makes sense if you believe in defence in depth with many layers of protection. Using the pepper without simultaneously using a per user salt, means you don't know what you are doing. The per user salt is easier to implement than a pepper value stored in the application code itself, and the per user salt also provides more security.
The proper name for these "Slow functions" is Key Derivation Function.
They are related, but not exactly the same. The slow functions that I was suggesting does not require every bit of their output to be unpredictable. It just requires that the output as a whole to not be easily computable. It doesn't matter if it turns out some long subsequence of the slow function output is easily computable. There is also no requirement that the output of the slow function be random looking. It could start with a sequence of 1MB of zeros, as long as it is followed by something that cannot be computed as quickly. There is also no requirement that the slow function isn't reversible.
So a slow function as I suggest it is not guaranteed to be usable as key derivation function. OTOH it may be that any key derivation function would satisfy my suggestion for a slow function. But I am not entirely sure about that either. It boils down to the question about whether a key derivation function is required to be slow?
Can you point to a formal definition which shows the difference between a key derivation function and a cryptographic PRNG?
Some examples are crypt (obsolete, vulnerable) PBKDF-2 (repeated application of salt-and-hash), bcrypt (repeated rounds of a special extra-slow variant of blowfish), and scrypt (an attempt to defeat GPU and custom hardware attacks by requiring lots of low-latency RAM).
What would you do if you are required to design an ultra secure password protection based on the above? You have four suggestions, but you might then be faced with the requirement that every stored password must be secure against an attacker who can defeat three of the four candidates. You need something that is secure as long as one of the four is not broken, but you don't know in advance which of the four.
If the formalization I was suggesting was being used, then you could just compute all four and concatenate them. You'd still need a hash function, and composing multiple candidate hash functions into one secure hash functions is harder. But you'd just a cryptographic hash function, which means simpler requirements than the more complicated primitive.
Claiming that a hash function is insecure because it is fast would be like claiming AES128 is secure because you can derive the decryption key from the encryption key.
That obviously should have said "Claiming that a hash function is insecure because it is fast would be like claiming AES128 is insecure because you can derive the decryption key from the encryption key."
Put differently. If you use AES when you should have used RSA, you don't blame AES for being insecure. If you use a SHA512 when you should have used a slow function, you shouldn't blame SHA512 for being insecure.
When you reason about the security of cryptographic systems, you usually show how many times a certain primitive must be invoked to break it. And if that number is large (usually meaning 2^128 or more), then you consider the system to be secure. It is not threat if the primitive itself is fast, because once you have to execute it 2^128 times, it will still take "forever".
But for protection of weak passwords you can't give such guarantee. Those can be broken with a relatively small number of invocations of the primitive. At that point the resources it takes to compute the primitive matters, and adding another requirement to a primitive means it is no longer the same kind of primitive.
This is a common misconception. The source of this misconception is the way people have tried to protect weak password through the use of hashing. If you take a strong password and hash it with a hash function satisfying all the requirements for a cryptographic hash function, then that password is well protected. That construction doesn't work for weak passwords. If you apply a salt while hashing, you move the threshold for the strength of passwords which can be brute forced. This is quite clearly an improvement over plain hashing. I know of no cryptographer, who has disputed, that it is a good idea to use salts while hashing passwords.
But there are still some passwords, which are too weak to be protected by a salted hash. This has lead to some people saying this hash function is insecure, because it is too fast. What they should have been saying was, this password mechanism is insecure, because it is using the wrong kind of primitive. This is an important distinction. Even if the hash function satisfies all the requirements of a cryptographic hash, then a salted hash cannot protect a weak password.
When building cryptographic systems you often need to apply different classes of primitives. Common primitives are hash functions, block ciphers, asymmetric encryption, digital signatures. Examples of primitives in each of these four classes are SHA512, AES128, RSA, RSA (yes RSA does fall in two different classes, there are other primitives, which fall in only one of those two classes). If you want to send an encrypted and signed email, you typically use all those four classes of primitives.
To protect semiweak passwords better than through a salted hash you really need a new class of primitive. For lack of better term I'll call that primitive a slow function. Claiming that a hash function is insecure because it is fast would be like claiming AES128 is secure because you can derive the decryption key from the encryption key.
The formal properties I would say a slow function should have are first of all that it is a (mathematical) function mapping bitstrings to bitstrings, and that it requires a certain amount of computing resources to compute the full output from any single input. Properties that I would not require a slow function to have includes collision resistance and fixed size outputs. Those are properties you expect from a hash function, which is a different kind of primitive.
People have tried to squeeze both kinds of properties into a single primitive, which if they succeeded, would be both a cryptographic hash and a slow function. But they haven't always paid attention to the differences in requirements. And often the result has been called a hash function, which confuses people, since it is different from a cryptographic hash.
One nice property of slow functions as I would define them is that given multiple candidate functions, you can just compute all of them and concatenate the results. And you will have another slow function, which is guaranteed to be at least as strong as the strongest of the functions you started with.
Once you have all the primitives you need, you can combine them into a cryptographic system, that achieves some goal. If you want to protect passwords, I think you are going to need both a slow function and a hash function. For the combined system, you actually give a formal proof of the security. The proof of course assumes, that the underlying primitives satisfy the promised criteria. I guess the password protection you would implement given the above primitives would compute the slow function on the password, and then compute a hash of password, salt and output of the slow function.
Additionally you could prove that the regardless of the strength of the slow function, the password as well protected as it would have been with just a salted hash. That way by handling those as separate primitives, you can reason about the security assuming the failure of one of the primitives. Such a construction would eliminate the main argument about some of the existing slow functions, which is that they haven't had sufficient review.
Seriously, we're not going to get out of this galaxy alive.
We are not. But our descendants might. I think that gas is the least problem when leaving the galaxy. It might be hot, but if it isn't very dense, then that might not matter.
You are mixing up terminology. 6to4 is a tunnelling method. It requires both ends of the connection to talk IPv6, but the network between them can be IPv4 only. It works great as long as both ends are using 6to4. Unfortunately we don't have enough IPv4 addresses to deploy IPv6 that way, and 6to4 and native IPv6 don't play well together. The problem is that in order for 6to4 and native IPv6 talking together, you rely on third party relays. With two different relays being used for traffic in the two directions, and many of the public relays not being very reliable, you end up with flaky connectivity. I actually developed a new method for tunnelling IPv6 over IPv4, where I managed to get the best of both worlds.
But I don't think what you have in mind is tunnelling. There is this thing called NAT64+DNS64. When a client is using IPv6 only sends an AAAA query to a DNS server with DNS64 support, the DNS server can look up the IPv4 address and translate it into an IPv6 address. Then the NAT64 unit can translate all the packets to put a number of IPv6 only clients behind a single IPv4 address. That way you can run the access network as IPv6 only and still talk to IPv4 only servers. But I don't know of any protocol who works better through NAT64 than it would through a carrier grade NAT44 solution. Running dual stack on the access network with RFC1918 addresses is most likely going to be better for the users than NAT64.
But neither of those NAT methods work for anything other than a pure client-server model with the server on a public IPv4 address. Any protocol that does not fit directly into that model will break, and the best solution for that is to deploy IPv6 to all the parties that need to communicate.
That will not work. The IPv4 only node will need to communicate with some IPv4 address, and there is none to be used for that purpose. If you read the other replies to your post, you will see that they seem to disagree with each other. That is because there are actually two different formats. There is the deprecated ::/96 prefix, and there is the currently used ::ffff:0:0/96 prefix. The later is used such that applications can use a single socket to talk both IPv4 and IPv6. It is entirely an API feature. Those addresses are never send on the wire. The actual traffic on the wire is IPv4 from one end to the other.
There are NAT solutions which will help a bit. There is NAT64+DNS64 if your LAN is IPv6 and backbone is IPv4. And I have developed a system for a LAN running IPv4 connecting to a backbone running IPv6.
In the ideal world, that would be true. In the real world, IPv4 addresses have run out in some parts of the world already. And yet more than 95% of the Internet is still IPv4 only.
True. But dual stack would have been the simplest way to transition from IPv4 to IPv6, as long as it was done before IPv4 addresses ran out, and all sorts of workarounds got in the way. The fact that dual stack is more complicated than running just one protocol by itself is of course a contributing factor to people hesitating with deploying IPv6. But you cannot blame that on the design of the IPv6 protocol. Nobody have provided a serious suggestion for a better design.
We could have had dual stack for a while and then dropped IPv4 support before the IPv4 addresses ran out. That would not have been as ugly, as what we can expect to see now. There is one good thing to say about dual stack though. If you mess up while changing network configuration remotely, you have a fallback, since misconfigured IPv4 can be fixed by logging in over IPv6 and vice versa.
You do if you need to communicate with somebody else who does not have an IPv4 address. And since ISPs have been handing out fever IPv4 addresses than the number of devices to be connected for the last 15 years or so, there is actually already a lot of devices, which do not have IPv4 addresses. Unfortunately, most of those don't have IPv6 addresses either.
That joke was funny April 1st of last year. http://packetlife.net/blog/2011/apr/1/alternative-ipv6-works/
IPv6 is simpler than IPv4.
That's just a lame excuse. There are some new features, but those are mainly important to the endpoints. For routers in between, the job they need to do became simpler. And it is the network, which has been lacking, not the endpoints. The excuse that it is too complicated has mainly been used by those who didn't need to deal with the complexity.
Name one change that affected a network provider, who just has to move packets between two endpoints.
No. There were only two approaches that could have speeded it up. Top down regulation or customer demand. But both of those were in the hands of people who won't understand the problem until they can no longer get online. Actually, there is one other thing that could have speeded it up. If we had never gotten any sort of NAT for IPv4 in the first place, then the transition would have gone faster.
I think the proper definition would have to include: "An adversary who has spent x% of the resources required to compute the output has at most x% probability of guessing the correct output." In reality the actual probability as function of the time spent isn't going to grow linear, but more likely as a convex function. The definition just requires a linear upper bound, which in some cases could be much higher than the actual probability.
Then how come I never see the number of hops between two endpoints vary as packets occasionally take a longer path than they should have? When switching and routing, you need to be able to buffer packets. (If output port is idle and running at the same speed as the input port, packets can be forwarded without buffering, but that's rarely the case on the entire path). When you need to be able to store the packet, then you can spend more time finding the correct destination. If you know the destination by the time half the packet is received, then it is far better to store and forward than to send it down the wrong path.
Ethernet has a minimum packet size, which is longer than the header. But not all equipment can handle packets at wire speed if they are all of minimum size. There is a reason why there is a desire to increase the maximum packet size. If 500 bytes can fly by before you know where to send the packet, then you buffer those bytes, and that may mean packets have to be larger than 500 bytes on average in order to achieve wire speed. Though the minimum packet size does help a little bit here, the reason there is a minimum size is actually something different. Originally the minimum size was in the standard to ensure that packets were long enough to reach from one end of the cable to the other.
I can say with 90% certainty that you got the number of dimensions wrong. If you left out the number of dimensions, your theory would sound plausible. Look at the quantummechanical duality between particles and waveforms. It looks like a clever hack to simulate continuous physical phenomena with a quantized representation in the simulation. Can anybody come up with a more plausible explanation for why that duality exists? I am just hoping I'll be the one to discover the vulnerability that will allow me to break out of the sandbox. It would give me access to all knowledge in the universe and unlimited computational power.
I doubt that he could have taken the video down in the first place. Google has a five digit number of employees. They do not all have access to remove videos from YouTube. I would have checked what the article had to say on that matter, but the link is broken.
You forgot the more sensible option. Comply with the law and stay in your job.
Nobody is saying that 95% is better than 99%. If there is 95% certainty that automatic cars are safer, would you rather be using manual or automatic cars? Is anybody going to say that they would rather use a manual car because there is only 95% certainty, that the automatic car is safer?
As for the 99% we'll get there over time. But even before there is enough data to reach the 99% you still need to make decisions on what to do until then.
I guess you are right, but in that case I'd argue that they have been answering the wrong question. What we really want to know is whether automatic cars or manual cars are safer. And the answer they can provide says, we don't know.
Faulty cars can cause accidents, even if they are driven manually. If you could save 10 out of every 100 people killed in traffic, wouldn't you want to do it? Or do you really rather want a 100 people killed, where you can put the blame on some person, than have 90 people killed where you cannot find a person to blame?
Or put differently, if you had 90 people getting killed in accidents, would you really want to sacrifice another 10 lives just so you can put the blame for the first 90 on somebody?
My point is, the ability to put the blame on somebody is not important. What is important is the total amount of accidents.
But what does side of caution even mean in this case? What if you instead of 99% confidence only had 80% confidence? It would mean that there is at least 80% chance that an automatic car is safer, so in other words is there at most 20% chance that a manual car is safer. How does the principle to err on the side of caution lead you to choose the approach, which has less than 20% chance of being the safest of the two?
Supporting two or supporting an arbitrary number is about the same amount of work. If you only support one at any given time, you are going to have chaos when you change it and every single user password stops working. And you are going to have problems as you gradually roll out the change, as anybody who have worked with production systems know you should do.
Besides, if you immediately expire all the passwords on a leak of the pepper value, there wasn't any point in using that value in the first place.
For those users who have chosen a strong password in the first place, there is much higher risk that somebody takes over their account due to an insecurity in the password reset procedure than there is of the password hash being broken. Even if the password is hashed just one time using MD5 and not using any salt or pepper, a strong password is still secure.
Want to prove me wrong on the MD5 claim? I generated a strong password, MD5 hash of that password is ccd8af43e22f5662cb3d021e222da920, MD5 hash of password followed by newline is 9f0dc9d398dbc503d816fd2ba4b4d1ee, MD5 hash of password followed by carriage return and newline is c256fe8a5c59e7c50a44bd1ee94d6e0f. I don't think anybody will ever invert any of those three MD5 hashes.
You are assuming that the slow function is used in an insecure high level design. The way cryptographic systems are designed is to take primitives where you make assumptions about the security properties of the primitives, then you put those primitives together in a high level construction, where you prove that it is secure. The proof relies on the security properties of the low level primitives.
When done this way, you cannot break the high level system. You can only break the primitives. If you do break one of the primitives, the high level system would become insecure until you replace the broken primitive with another primitive of the same class, but not broken yet. For example many constructions use cryptographic hash functions. If you have such a system using MD5, then it is insecure. But if you were to replace MD5 with SHA512, then it would be secure again.
At no point did I say the slow function was supposed to difficult to invert. If you design a high level protocol with the assumption that the slow function is difficult to invert, you are at fault for designing the high level protocol incorrectly. This is just as bad as assuming that a cryptographic hash function is slow to compute, which is not one of the accepted assumptions about a cryptographic hash function.
I did point out that I expect the slow function to be combined with a cryptographic hash function. In fact the only sensible thing you can do with the output of a slow function as I described it is to pass it through a cryptographic hash function (perhaps combining with other data, which could be as part of an HMAC construction). The point is that each of the primitives serves a well defined purpose, and you can reason about them independently.
That is a valid point. And that is something that the formal definition would need to take into account. But to address that point it is sufficient that the probability of two inputs producing the same output is small, it does not need to be negligible.
For example if the probability that two random inputs produce the same output is 10^-10, then it is impractical to rely on collisions if you want to break passwords. It would be much more efficient to simply compute the slow function than to test enough passwords to find the one where the 10^-10 chance of producing the right output comes out in your favour. So given today's computational power a 10^-10 probability is small enough. On the other hand a hash function with 10^-10 probability of collision between any random pair of inputs is absolutely not collision resistant. You only need to evaluate such a hash function on roughly 10^5 inputs to find a collision. Even if each input took five seconds to hash, it would only take a week to hash enough inputs to find a collision.
So, the requirement that would be needed would be much weaker than collision resistance. Moreover the probability of two inputs producing the same output is something that has been considered for non-cryptographic hash functions in the past. And there are even constructions with formal proofs of such probabilities. And for those constructions I am not talking about something that relies on assumptions about the security of some cryptographic primitives. For example if you want to produce message-authentication-codes using a shared secret, it can be done provably secure. And a large part of the construction comes from hash functions with a known probability of collisions.
That little detour was just to point out some of the work in that area, which could be relied upon. Now getting back to the slow functions, I should elaborate on something I said earlier.
The part about not requiring fixed size outputs is a bit more important than it may seem from what I wrote. If you look at input and output sizes of hash functions and PRNGs you'll find a difference. Whether you are designing a cryptographic hash function or a PRNG, you want the output to be indistinguishable from random. The most important difference between those kinds of primitives is that you use a hash function when you want the output to be small and a PRNG when you want the output to be larger than the input.
A hash function always produce outputs of the same size, which in most applications is smaller than the input, hence collisions are guaranteed to exist, but may be hard to find. A PRNG always produce a output that is larger than the input.
The slow functions I suggest do not require the output to be nearly as random looking as that of a hash function or a PRNG. They also don't have to produce outputs of some specific size, the output can be smaller or larger than the input. But in order to satisfy some of the other requirements it is a good idea to produce a large output. It is easy to avoid collisions if the output is larger than the input. If you design a slow function from the start to satisfy the definition I suggest, it may as well append every single intermediate calculation along the way to the output. As such a slow function is being evaluated on a tiny password, the output may very well be multiple MB in size.
That is another reason why I would imagine the slow function being combined with a cryptographic hash. Any design involving a slow function is almost certainly going to pass the output through a cryptographic hash with the usual collision resistance requirement.
The main point with my proposal to split the hashing and slowness into separate is that each of them have a much smaller set of requirements, and thus a much smaller set of possible vulnerabilities. The specific problem you mention is not considered a major threat, but my proposal still protects against it.
In my suggested model, the slow function is where you could choose to use an iterated hash function. But there is no requirement that the slow function preserves all of the entropy. If the slow function was to lose a bit of entropy, that would not be a major problem. If it lose so much entropy, that the output is completely predictable, then it is a real problem. But you'd be able to demonstrate the entropy leak by using the birthday paradox to find an example collision a long time before the lost entropy became a real problem.
The point of my construction is, that you can still argue about the security of the system even if the security of the slow function completely breaks down. The worst case for the slow function would be if the output was constant (if every input results in the same output, you just need to compute it once). But even in that case, you can make a full system, which requires one invocation of the cryptographic hash for every password that is attempted.
Protecting against the entropy loss in iterated hashing is by now means a new idea. What I think is a new idea is that of splitting the slow part and the hashing into separate primitives and providing two proofs for the security of the system with a broken slow function and with an unbroken slow function.
No need for the additional overhead of using a rainbow table for this. Just apply a generic brute force dictionary attack without using rainbow tables. It will be much faster, if there is just a single leak.
The rainbow table only helps if it can be precomputed, which you can only do if that salt is leaked before the database. If a site repeatedly have leaks of their password database, and the salt remains unchanged between leaks, then for any subsequent leak the salt is previously known, and a rainbow table can be used. But after the second leak the only users still using the site will be those who don't care about security anyway.
That is correct, and it should change whenever the user update their password. You can combine the two and have one value, which is constant for the site and one that is unique for every user. It is the salt, which is unique for every user, that provides the majority of the security. The other value, which is fixed for all users on the site is sometimes referred to as pepper. If the pepper value is leaked, it provides no additional security, but you still have the security provided by the unique salt values. But if the pepper value is not leaked, then nobody can even start brute forcing the password hashes or compute a rainbow table, even if the entire password database is leaked. That gives more time to get passwords changed, if you are lucky and only the password database is leaked and not the pepper.
For example if the pepper value is a hardcoded value in the source code for the site, then it doesn't have to be present anywhere in the password database. Some attacks cause a leak of only one of the two, and in those cases you have more time to get passwords changed. If they are leaked simultaneously, you are left with only the security of the salt, which is what you'd have, if you weren't using pepper in the first place.
If either the pepper or the database is leaked, you have to change the pepper value (as soon as you have closed the hole, which allowed the leak in the first place). But until all passwords have been changed, you still have to support the old pepper value. That means to properly use this, you need to have a hardcoded array of pepper values in the application, and store an array index in the user entry in the password database.
The use of such a pepper value makes sense if you believe in defence in depth with many layers of protection. Using the pepper without simultaneously using a per user salt, means you don't know what you are doing. The per user salt is easier to implement than a pepper value stored in the application code itself, and the per user salt also provides more security.
They are related, but not exactly the same. The slow functions that I was suggesting does not require every bit of their output to be unpredictable. It just requires that the output as a whole to not be easily computable. It doesn't matter if it turns out some long subsequence of the slow function output is easily computable. There is also no requirement that the output of the slow function be random looking. It could start with a sequence of 1MB of zeros, as long as it is followed by something that cannot be computed as quickly. There is also no requirement that the slow function isn't reversible.
So a slow function as I suggest it is not guaranteed to be usable as key derivation function. OTOH it may be that any key derivation function would satisfy my suggestion for a slow function. But I am not entirely sure about that either. It boils down to the question about whether a key derivation function is required to be slow?
Can you point to a formal definition which shows the difference between a key derivation function and a cryptographic PRNG?
What would you do if you are required to design an ultra secure password protection based on the above? You have four suggestions, but you might then be faced with the requirement that every stored password must be secure against an attacker who can defeat three of the four candidates. You need something that is secure as long as one of the four is not broken, but you don't know in advance which of the four.
If the formalization I was suggesting was being used, then you could just compute all four and concatenate them. You'd still need a hash function, and composing multiple candidate hash functions into one secure hash functions is harder. But you'd just a cryptographic hash function, which means simpler requirements than the more complicated primitive.
That obviously should have said "Claiming that a hash function is insecure because it is fast would be like claiming AES128 is insecure because you can derive the decryption key from the encryption key."
Put differently. If you use AES when you should have used RSA, you don't blame AES for being insecure. If you use a SHA512 when you should have used a slow function, you shouldn't blame SHA512 for being insecure.
When you reason about the security of cryptographic systems, you usually show how many times a certain primitive must be invoked to break it. And if that number is large (usually meaning 2^128 or more), then you consider the system to be secure. It is not threat if the primitive itself is fast, because once you have to execute it 2^128 times, it will still take "forever".
But for protection of weak passwords you can't give such guarantee. Those can be broken with a relatively small number of invocations of the primitive. At that point the resources it takes to compute the primitive matters, and adding another requirement to a primitive means it is no longer the same kind of primitive.
This is a common misconception. The source of this misconception is the way people have tried to protect weak password through the use of hashing. If you take a strong password and hash it with a hash function satisfying all the requirements for a cryptographic hash function, then that password is well protected. That construction doesn't work for weak passwords. If you apply a salt while hashing, you move the threshold for the strength of passwords which can be brute forced. This is quite clearly an improvement over plain hashing. I know of no cryptographer, who has disputed, that it is a good idea to use salts while hashing passwords.
But there are still some passwords, which are too weak to be protected by a salted hash. This has lead to some people saying this hash function is insecure, because it is too fast. What they should have been saying was, this password mechanism is insecure, because it is using the wrong kind of primitive. This is an important distinction. Even if the hash function satisfies all the requirements of a cryptographic hash, then a salted hash cannot protect a weak password.
When building cryptographic systems you often need to apply different classes of primitives. Common primitives are hash functions, block ciphers, asymmetric encryption, digital signatures. Examples of primitives in each of these four classes are SHA512, AES128, RSA, RSA (yes RSA does fall in two different classes, there are other primitives, which fall in only one of those two classes). If you want to send an encrypted and signed email, you typically use all those four classes of primitives.
To protect semiweak passwords better than through a salted hash you really need a new class of primitive. For lack of better term I'll call that primitive a slow function. Claiming that a hash function is insecure because it is fast would be like claiming AES128 is secure because you can derive the decryption key from the encryption key.
The formal properties I would say a slow function should have are first of all that it is a (mathematical) function mapping bitstrings to bitstrings, and that it requires a certain amount of computing resources to compute the full output from any single input. Properties that I would not require a slow function to have includes collision resistance and fixed size outputs. Those are properties you expect from a hash function, which is a different kind of primitive.
People have tried to squeeze both kinds of properties into a single primitive, which if they succeeded, would be both a cryptographic hash and a slow function. But they haven't always paid attention to the differences in requirements. And often the result has been called a hash function, which confuses people, since it is different from a cryptographic hash.
One nice property of slow functions as I would define them is that given multiple candidate functions, you can just compute all of them and concatenate the results. And you will have another slow function, which is guaranteed to be at least as strong as the strongest of the functions you started with.
Once you have all the primitives you need, you can combine them into a cryptographic system, that achieves some goal. If you want to protect passwords, I think you are going to need both a slow function and a hash function. For the combined system, you actually give a formal proof of the security. The proof of course assumes, that the underlying primitives satisfy the promised criteria. I guess the password protection you would implement given the above primitives would compute the slow function on the password, and then compute a hash of password, salt and output of the slow function.
Additionally you could prove that the regardless of the strength of the slow function, the password as well protected as it would have been with just a salted hash. That way by handling those as separate primitives, you can reason about the security assuming the failure of one of the primitives. Such a construction would eliminate the main argument about some of the existing slow functions, which is that they haven't had sufficient review.
We are not. But our descendants might. I think that gas is the least problem when leaving the galaxy. It might be hot, but if it isn't very dense, then that might not matter.