Score:1

The Responsibility of Key Exchange

us flag

I've been implementing an asymmetric key exchange for creating a symmetric key.

My question is more of a philosophical/legal one in terms of key-exchange responsibility, and what happens when let's say, a commonly known key is used.

I'd like to set these base variables:

  • The client has the servers public key hardcoded in memory
  • The server has its private key hardcoded in memory
  • There is a hardcoded nonce_size
  • There is a hardcoded public_key_size
  • There is a hardcoded mac_size

The steps of communication for exchange are as follows:

  1. After successful TCP connection, client generates new public key client_pubkey, encrypts its own public key client_pubkey using a new nonce temp_nonce_1 and the hardcoded server_pubkey, and sends a message where the first bytes are the nonce, and the rest are the encoded client_pubkey (including its mac). This has a known size of nonce_size + public_key_size + mac_size.
  2. The server receives a message, checking its size for exactly nonce_size + public_key_size + mac_size. If it is, it assumes it is a key exchange. It decrypts the public_key. The server then generates a new symmetric_key, and sends a message back containing a new nonce tmp_nonce2, and the symmetric key + mac encrypted using the received client_pubkey.
  3. The client receives this message, knows exactly what size it should be otherwise it rejects. The client now has a symmetric key to use.
  4. Server and client communicate through the symmetric keys.

So here is my attempt at understanding why this is secure:

  1. In the case of random garbage bytes being sent to the server, the server generates a key, encrypts key using garbage, creating more garbage, and then sends that. So in reality, we have sent out more garbage, and then we just never receive a valid message and eventually timeout, closing connection. The only harm here is wasted CPU time for a few seconds.
  2. The client specifically sends a public_key of just zero's (or some other obvious bitset, like all 1's) and a valid (or also zero) nonce. In which case the server treats the zero's as the public key and sends a symmetric key encrypted via the public key zero's. However, this should still be safe because having the public key of zeros assumes you know the private key that said zero public_key is derived from, which would potentially take billions of years to reverse-engineer, so it is still safe.
  3. Assuming the client and server can restart this process infinitely (and there is no x-try limit on the server), assuming somehow by sheer incalculable luck and sending random bytes, a key exchange occurs, and a valid message of whatever data the server was expecting is sent and parsed by server, we throw our arms up in the air as it is approachable nearly impossible and basically shit happens.
    • In this case, we can't say anyone is liable can we? There is nothing that the server can do about knowing it to be a malicious packet.
    • Even if we had an x-retry limit of 2 attempts, it could theoretically even occur on the very first connection from an IP address, and again there is nothing we can do about it.

So basically, everything is secure because the basis of the very first message is expected to be encrypted by a public_key that only the server should know the matching private_key of, right? And that in the sheer case that something, somehow, ever does manage to get through, the outcome is thrown to the undefined?

I am sorry if this is really terse, I am just trying to verify both my understanding of the theory and ensure there is no mistake in the implementation of such a protocol.

Maarten Bodewes avatar
in flag
I don't get it, why encrypt something with a nonce, and then send the nonce together with the ciphertext? What's the point of that?
fgrieu avatar
ng flag
Also, it's assumed the encryption used is size-preserving. But any size-preserving encryption is deterministic, thus fails under a CPA indistinguishability experiment. While that's not an issue here, it removes generality to the construction.
DeathDream avatar
us flag
@MaartenBodewes From what I understand, the point of the nonce is to make it so subsequent messages with the same key cannot discover a common "block/component" in the encrypted message, and use that in a decipher attack. But in the case of a key exchange where the hard encoded public key is used to generate a new public key, and the server decrypts the message once (using its private key) and encrypts a random key again, the nonce may be useless in this case I guess? I guess we have to rely on the client not-self compromising itself?
DeathDream avatar
us flag
@fgrieu In the real world, we have to enforce some form of size constraint though don't we? For example, if we are encrypting messages in UDP land, and we are really constrained to sending packets within a 512 byte message size so we can guarantee they are deliverable (which from what I understand is the only maximum size limit we can guarantee unless you are in ipv6 land), then we only have a maximum size of 512 bytes to work with. Whether or not the encryption is size preserving, the maximum size difference would have to be guaranteed to fit within 512 - message size bytes.
SAI Peregrinus avatar
si flag
This is a *really weird* protocol. What if a legit message happens to have the same length as `nonce_size + public_key_size + mac_size`? How are you encrypting things with asymmetric keys, that's not normal. Normally one uses a KEM or some sort of Diffie-Hellman-like key exchange (most often ECDHE). Why is message 1 "encrypted" at all, when all the info that goes into the encryption key is public? Have you seen the [Noise protocol framework](https://noiseprotocol.org), and if so why aren't you using that to design a protocol that's sane?
SAI Peregrinus avatar
si flag
For that matter, why aren't you using TLS? 99% of the time, for transport encryption to a server TLS is what you want.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.