# HMAC based Key exchange

Alice and Bob need to share public keys to sign/verify ephemeral keys. They have a secret key $$K$$.

1. Alice generates a 32 bytes random number $$A$$, computes $$\operatorname{HMAC-SHA256}(K, M||A)$$ and sends Bob the hash and plain $$M$$, $$A$$
2. Bob computes $$\operatorname{HMAC-SHA256}(K, M||A)$$ to check the hashes
3. If hashes match, Bob computes $$N=\operatorname{HKDF}(A||K)$$
4. Bob encrypts his public key $$E_N(\mathit{PubKeyBob})$$ using AES 256 GCM, and sends the cipher to Alice
5. Alice computes $$N$$ and decrypts the cipher, encrypts her public key $$E_N(\mathit{PubKeyAlice})$$, and sends Bob the cipher
6. Bob decrypts the cipher and they both have each other's public key

Is this a safe way to share public keys?

• Welcome to crypto.stackexchange - May I ask why the public keys need to be encrypted at all? Why can you assume the existence of a pre-shared secret, but not the existence of a pre-shared public key? – Ella Rose Sep 29 '19 at 22:26
• To prevent man in the middle attack. They have a pre-shared secret because they know each other. – civ15 Sep 29 '19 at 22:30
• If you have pre-shared $K$ why don't you just send the public keys encrypted with AES? – kelalaka Sep 29 '19 at 23:02

If they have a pre-shared key $$K$$ and want to authenticate public keys, the simplest way would be for Alice to compute $$T = HMAC(K, PubKeyAlice)$$ and send $$(PubKeyAlice,T)$$ to Bob. This authenticates the public key of Alice. There is no need to encrypt it, since it is a public value anyway.