I need to establish a secure method for transmitting shared secret keys between a mobile app and an API server to ensure the integrity of the data.

When initially exchanging shared secret keys, I'am employ X25519. However, if a previously established shared secret key exists for a user on the server, It must retrieve and use the shared secret key that is already stored for that user. Because altering the shared secret key by generating a new one would render it incompatible with other logged-in devices.

The threat model is for users to spoof the API by discovering their shared secret key.

To prevent this, I came up with three approaches.

First Approach:

  1. The server possesses an RSA or ECIES key pair. Server's public key is hardcoded into the client.
  2. The client generates a random AES key, encrypts it using the server's public key, and transmits it to the server.
  3. The server decrypts the received encrypted AES key with its own private key, encrypts the message with that key, and sends the value to the client, including signing it with the private key.
  4. The client decrypts the received encrypted message with the AES key and verifies the signature with the server's public key.

Second Approach:

  1. The client has an RSA or ECIES key pair.
  2. The client sends its public key to the server.
  3. The server encrypts the message using the public key received from the client and transmits it.
  4. The client decrypts the encrypted message received from the server with its own private key.

Third Approach:

  1. Both client and server have RSA key pairs.
  2. The client sends its public key to the server.
  3. The server encrypts the message with the client's public key and generates a signature with its own private key. It sends the encrypted message, its signature, and its own public key to the client.
  4. The client verifies the integrity of the signature by verifying it with the server’s public key and decrypts the encrypted message with its own private key.

Which of the three approaches above best suits my situation? Or if you have any other insights or solutions, I'd sincerely appreciate your input.


1 Answer 1


The second and third approach don't make sense. You cannot simply send a public key over an insecure channel, because an active man-in-the-middle attacker could replace it with its own key, rendering the entire encryption useless.

In the third approach, it also doesn't make sense for the server to send both the message signature and the public key for verifying the signature. This provides no useful information. Anybody can generate a key pair and calculate a signature. If you don't know the public key in advance or have some way of verifying it (like checking a CA signature in TLS), the signature is meaningless. You might as well replace it with text saying “This data is correct”.

On top of that, the client in the second and third approach has no way of authenticating the server. They send a public key over an insecure channel, so any man-in-the middle attacker can see it. They get back a message encrypted with the public key, which anybody who knows the key can do. So the client is essentially transmitting their key into the dark, and they receive an entirely unauthenticated message which could come from anywhere.

In general, it's a very bad idea to come up with a new protocol, because even seemingly simple steps often turn out to be very difficult to get right, and minor mistakes can make the entire protocol insecure. Even professionally designed protocols have to go through years of peer reviews and fixes until they're reasonable secure.

So the answer is: Use a standardized protocol. The obvious choice would be TLS which can be used in many different ways (not just via HTTPS).

With TLS, the key transmission is simple:

  • Client and server establish a TLS connection. As part of this, the server authenticates to the client with a certificate signed by a trusted CA.
  • The client authenticates to the server -- be it with a password, an API key, a client certificate or any other secure method.
  • Since there's now a secure channel, and both parties have mutually authenticated, the server can send the key to the client.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .