Assuming that Alice and Bob know the hash of each other's public key, take this method:

  1. Use ECDiffieHellman with temporary private keys each time to generate a per-session shared symmetric key
  2. Create an AES connection secured with the shared key (unique IVs for each message, verified with HMAC)
  3. Send their public keys along with their signatures of that particular session key over the encrypted connection to authenticate each other (by verifying that the public key matches the stored hash, and that the signature was signed by the public key).

Is this a safe way to create a secure and authenticated session? Are there any better ways that do not require pre-existing knowledge of the private key (or trust in a centralised certificate authority). I know that you should always try to use standard libraries, but I am interested in understanding more about cryptography - this will not be used in any critical software.

Thanks very much for your help.

  • $\begingroup$ Regarding step 2: How do Alice and Bob determine the shared key if they only know hashes of their public keys? $\endgroup$ – VincBreaker May 10 '20 at 13:28
  • $\begingroup$ @VincBreaker Sorry for being unclear - they generate the shared key using two temporary private keys (so that the key is different for each session). These temporary keys are different to the private keys tied to their identity (which do not change). $\endgroup$ – Miles Watson May 10 '20 at 13:37

Sure, first you set up a 1:1 communication and then you establish trust in it. This is kinda like TLS 1.3 where encryption starts as soon as possible. Of course, anything up to the authentication of the entity and handshake can be generated by an adversary, so it is slightly dangerous in that sense.

And in general, you would try and authenticate as many handshake parameters as possible, rather than just the ongoing channel. Basically you try and tend to achieve confidentiality and authentication over as much data as possible. You could do that by hashing all the communication messages and then signing that separate hash, for instance.

As for the trust in the public keys: yeah, sure. This is almost identical to certificate pinning after all, where a certificate is trusted explicitly rather than just a public key. The advantage of using a certificate is of course that you can use a certificate chain later and that a certificate contains more information than just a public key (validity period, identification information, CRL and whatnot). So generally if you want to use a public key, why not create a self signed certificate for it and pin that instead.

The described scheme can certainly be part of a secure protocol. If the protocol is actually secure depends on a lot of other factors. And such details matter even for the specific scheme mentioned (parameter validation, side channel resistance, avoidance of replay attacks and mirror or reflection attacks), and so on. Creating a secure transport protocol is one of the most daunting tasks, especially for a beginner.

  • $\begingroup$ Indeed, the principle of the protocol is sound. But to my taste it is not described with enough details to be vetted secure. Two potential problem areas: A) insufficient validation of the other's party temporary "public key" received in ECDH, which could allow an adversary to force the use of a chosen session key (e.g. replacing that temporary "public key" with the point at infinity for both sides, but there could be variants to the same effect). B) failure to derive separates symmetric keys in each direction, allowing an adversary hijacking a session after establishment to play some games. $\endgroup$ – fgrieu May 10 '20 at 17:40
  • $\begingroup$ @fgrieu I've added a section to the answer just to indicate that this is only the start of securing a connection. Do you know what the attack is called when a message of the sender is replayed towards the originator itself? I don't think "replay attack" captures that kind of scenario. $\endgroup$ – Maarten Bodewes May 10 '20 at 17:49
  • 1
    $\begingroup$ I know that as a mirror attack or (equivalently) reflection attack. $\endgroup$ – fgrieu May 10 '20 at 19:02
  • $\begingroup$ @MaartenBodewes I use a hash set to store the previous HMACs for the session, and check that the HMAC hasn’t been used before. Would this help to prevent the replay/mirror attack? $\endgroup$ – Miles Watson May 13 '20 at 8:19
  • $\begingroup$ Maybe not the most efficient and you have to watch out for collisions, but sure that can work fine when implemented correctly. $\endgroup$ – Maarten Bodewes May 13 '20 at 12:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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