These are two pretty fundamental problems.
That's not going to work, so we need to make some improvements here.
The way to solve this problem is to include more randomness in the key here,
so an attacker who can replace this won't be able to trick the parties into agreeing
to a different key, and then they can verify that they've agreed on the same key.
What we're going to do is add extra random nonsense to these steps.
In addition to the messages, the client will generate a random value--we'll call that rc--
that will be added to this message.
The server will generate a random value rs that will be added to this message.
This value will still be created.
This is what's call the premaster secret.
What we're going to send here is going to include a little extra information.
It's still going to include r--the premaster secret. We need to share that with the server.
We're going to pad this.
This will make search attacks more difficult, prevent some of the weaknesses.
If this is a message, happens to be a small number.
We're going to use the PKCS protocol that we talked about in Unit 4
to use RSA more securely.
If this were some other cipher, we could use a different way of padding it.
We're also going to add to r something about the client version,
and this will be useful for verifying the previous steps have not been tampered with.
Instead of making the key just r,
the key is going to combine all the randomness that we've used so far.
The way we'll compute the key, which is now called the master secret,
is by using a pseudo-random function--this is like a hash function--
where what it takes as inputs are the premaster secret--that's r--
and it also takes a label, which is just identifying this as the master secret,
which gets combined with the value of rc--the client's randomness--and the value of rs--
the servers randomness.
What H is is a way of using a combination of hash functions where it takes a key
as well as the value that you're hashing.
What it produces is 384 bits, which gets divided into three 128-bit keys.
One of these will be used as the key for symmetric encryption,
and that's using an algorithm like RC4, typically.
One of these will become the IV, and that's the initialization vector which we need for CBC--
cipher block chaining mode--that we'll use.
We'll talk about the protocol, how it uses that, later.
The other one would be a key that's used for a keyed hash.
We've previously talked about hash functions that didn't use a key.
The important property of the hash function is it gives us a one-way mapping.
A keyed hash function--that mapping depends on the key.
One way to think about that, which is not quite the way these work,
but it's really concatenating that key with the value we're hashing.
If it's a strong cryptographic hash function, that should be effectively equivalent to a keyed hash function.
This change means if an active attacker can interfere with this message,
they still can't control what gets computed here.
This depends on the randomness used in the previous two steps.
What happens before the channel is used for anything secure
is the client and server need to verify that they got the same key.
We add a step here to finish the handshake.
The way that step works is we encrypt the finished message,
using the key extracted from the master secret.
That means if any of these values were tampered with
that key would be different, the handshake would never be finished,
and there would never be any secure communication sent using that key,
because both parties verify the handshake before continuing.
This fixes the first problem.
Now there's no way for the middle attacker to hijack the session.
If they tamper with this message, it will be detected when the handshake finish is done
using a key that depended on all these values.
Depending on the random values here also prevents replay attacks.
Since new random values are used for each protocol execution,
there is no way to replay it.
The key depends on these values that were used previously.