Basically the title says it all. I am trying to develop and understand an ECDH-ECDSA encryption.

My current approach to provide some form of authentication to the ECDH is to use ECDSA to sign the public key of ECDH before sending it over the network, in order to allow the receiver to verify the sender.

However, after reading up on some ECDSA implementations, I am quite confused about the way ECDSA public keys are being handled.

In my implementation, I wanted to hardcode a static key pair into both sides, as I am not planning on making it a high scale public implementation. That way I don't have to expose my keys and fear any man in the middle attacks - given I understood everything correct.

However, most solutions seem to simply send the ECDSA public key over an insecure channel.

But isn't this what ECDSA is trying to prevent? Why is the algorithm doing exactly what it is trying to prevent itself?


1 Answer 1


The attack that we're trying to prevent is a Man-in-the-Middle attack; this is one where an attacker (who is assumed to be able to modify messages) can step into a negotiation. In effect, when Alice tries to negotiate with Bob, Mallet steps in, and so Alice actually negotiates with Mallet. Mallet can then negotiate with Bob (posing as Alice), and then, forward any traffic he gets from Alice to Bob, and any traffic he gets from Bob to Alice. As far as Alice and Bob are concerned, it looks like they have a secure connection (but Mallet can listen in to all their traffic, and also modify it at will).

To prevent this from being a possibility, Alice and Bob need to be able to do something that Mallet cannot. There are a couple of possible ways, including:

  • Alice already knows Bob's public key, and Bob already has Alice's public key.

  • Alice and Bob both have a certificate from a trusted certificate authority.

There are other possibilities; hwoever these two are relevant to your question.

However, most solutions seem to simply send the ECDSA public key over an insecure channel.

I would certainly hope not; as you can see, Mallet can generate his own ECDSA public key, and so this would do nothing to prevent a MITM attack.

What these solutions do is actually have Alice and Bob have certificates. What a certificate is is essentially a message "Alice's public key is [this], signed Trent" (where Trent is the friendly neighborhood CA). Trent gives Alice her certificate (based on Alice's public key) before negotiation ever happens, and Trent also gives Alice his public key. During negotiation, Alice gives Bob her certificate; Bob can then verify that a) the identity listed in the certificate is the perform Bob thinks he's talking to, and b) it actually is signed by Trent. If both are true, Bob then knows Alice's public key, and that can be used in the protocol. Mallet cannot generate such a certificate; Trent won't give a certificate to Mallet that lists Alice as the owner; Mallet cannot reuse Alice's certificate (as he doesn't know Alice's private key); Mallet cannot generate his own certificate (as he doesn't know Trent's private key).

So, once Bob knows Alice's public key (and similarly, Alice knows Bob's), they can then use the each other's public key to authenticate the ECDH exchange, and all is well.

One other thing I want to bring up:

In my implementation, I wanted to hardcode a static key pair into both sides

If you're not actually using a certificate authority, then you could have both sides generate a long term ECDH key pair, and just install Alice's public key on Bob, and Bob's public key on Alice. This would also foil a MITM attack (as Mallet can't replace the public keys with his own). There is an issue about updating the keys (we never want an immortal key; every key ought to have an expiry date), and there's no obvious way to update keys here.

Of course, if that's what you're doing, and you're happy with it, then it's not clear why you actually need to bring public key crypto onto the table. If Alice and Bob both share a Message Authentication Code (MAC) key, then during negotation, Alice and Bob can exchange nonces, and then both compute $\text{MAC}_{key}( Nonce_{Alice} | Nonce_{Bob} )$; that's a shared secret that's a whole lot faster and easier than ECDH.

The other concern is a potential device compromise attack (which may or may not be relevant to you). In this attack, we assume Mallet breaks into Alice, and learns all her secrets. Now, going forward, Mallet can then pretend to be Alice (and there's nothing we can do about that). However, with the ECDH preconfigured private keys (or the shared MAC key), what Mallet can do is go back and decrypt previously recorded communicates by Alice (because Mallet now keys Alice's private key). In contrast, in an ECDSA/ECDH scenario (where Alice and Bob select the ECDH keys randomly each time), he cannot (assuming Alice zeroizes all her keying material when she's done with it).

Now, obviously, and ECDSA/ECDH protocol will be more complicated then one just using ECDH. Is the extra complication warranted in your case? That, you have to decide for yourself.

  • $\begingroup$ Thanks poncho, that was very insightful. I also thought about hard coding ECDH keys, but I was (and still am) hesitant due to the missing forward secrecy and the key immortality. It seems like the guides I read either missed to mention certificates, or I just straight out missed that mention. $\endgroup$ Jun 20, 2017 at 15:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.