# Method to mitigate MitM attack for DH key exchange

Plain DH key exchange protocol is vulnerable to MitM attack. I checked the SRP (RFC 2945) but did not fully understand why it can help. I thought of a fix to mitigate MitM problem by using a pre-shared key:

1. Alice and Bob created a shared key via secure channel (face-to-face, off-line etc.), let's call it "psk" (short for pre-shared key).
2. They use DH protocol to setup a session key.
3. They both calculate final_key = HMAC(psk, session-key), and then use final_key to encrypt communication.

Since the middle man does not know psk, he cannot guess the actual key being used. So MITM does not work.

My questions are:

1. Will the above idea of a "pre-shared key" actually work? If so, is it in principle the same as any known standards or proposals? If not, what is the flaw?

2. Is it possible to defend against MitM without any pre-shared key?

1. Yes, it would work, but it has some serious flaws:

First, DH is often used when there's no opportunity to pre-share a key, such as when a user first visits a web site, or when an attacker might have stolen a pre-shared key.

Second, if you've got a pre-shared key you could just use that as the input key material to a Key Derivation Function in a Symmetric-key Ratchet. The Signal article on their Double Ratchet has a nice explanation of this (sections 2.1 and 2.2). This would be faster than a DH exchange.

Third, it needs a unique pre-shared key between every single pair of entities that might communicate. There are a few billion computers around. That would mean a few billion factorial, which would mean that storing these keys would take up more space to store the data than there are atoms in the observable universe.

1. Yes, in a way. The common way this is done is using signatures and a Public-Key Infrastructure.

There are asymmetric algorithms like ECDSA and EdDSA that allow someone to publicly share a key (and keep a second corresponding key private) and "sign" a message with their private key. A message signed using the private key can be verified by anyone with the public key.

Instead of pre-sharing all the public keys, a small set of Certificate Authorities (CAs) are given trusted status. These "root" CAs have their public keys bundled with operating systems and web browsers. The root CAs in turn sign special messages containing the public key of some other CAs (intermediate CAs) they trust to only sign legitimately created messages. Web site owners (and others) register their public keys with these intermediate CAs.

Simplifying a bit: when a user tries to connect to a web site the user sends a challenge (really the DH exchange) to the site to sign. The site then signs it, and sends the signature, their public key, and the chain of public keys and signatures of keys leading back to a root CA. The user's browser checks that the root CA key is one of the ones they trust, then verifies the intermediate CA key was signed by that root CA, etc, until they verify the signature from the challenge is correct. This page is a far more accurate (and more detailed) description of how this part works.

So only a few "root" CA public keys need to be widely shared, instead of having a unique pre-shared key for every pair of entities that want to communicate. That's an ENORMOUS space savings, and makes it far easier to create a new entity (imagine if web sites had to send a message pre-sharing their key to every single internet-connected device in the world to start working!)

• Thank you for the detailed explanation. It sounds reasonable, and is the key benefit of PKI, i.e. pre-shared key do not need to keep secret. Jun 4 at 0:39