I am making an API that uses the following steps for encryption. All of this is implemented using libsodium.

First of all the client has to make an initial request to the server for getting his public key and client token, with that key that corresponds to an unique sealedbox he encrypts and sends all the requests bodys. Once obtained he stores it locally

Then in order for the client to send a request to the server it has to encrypt the body ( create the sealedbox ) with the public key + ephemeral private key that's destroyed right after the encryption process.

Then the server takes the request and searches for the keypair generated for that client token in order to open the sealedbox.

When the server sends the response to the client is just a plain JSON

All connections to the server uses TLS 1.2+ + HSTS Header.

What do you think? Is it secure? Is there a better solution?

Do i need to implement Key exchange https://doc.libsodium.org/key_exchange in order to get the initial public key and client token to be completelysecure ?

  • 1) The traffic to the server is already encrypted with TLS. Why do you want to to encrypt it additionally? 2) To your question "Is it secure?" - even if you don't encrypt it is already secure. Secure against what threats do you mean?
    – mentallurg
    Dec 23, 2020 at 0:49
  • @mentallurg 1) Yes of course , 2) It’s very sensitive user data, so my primary objective is to reduce to the minimum the risk of accessing that data even if the network is compromised and make sure that who is requesting that data is that user ( client token ), it’s just an idea , that is why I ask if there exists a better way of achieve the same result Dec 23, 2020 at 1:05

1 Answer 1


TLDR: If you don't trust TLS, there is no easy way to establish secure data exchange.

You said that one of the threats is

the network is compromised

If you don't trust network, then sending client token via such network makes no sense. Also all further steps that you described make no sense because they are based on a compromised client token.

Another threat is compromised authentication:

make sure that who is requesting that data is that user

If you don't trust network, then you cannot trust user login. Means, you need to use some pre-shared secret which was shared via some other, trusted channel. For instance, you can send a list of one-time passwords to the client per SMS, or Email, or even per normal mail, or provide a one-time-password generator to each client.

Another approach may be using a separate public key on the server (for encryption of client requests) and public keys for each client. Actually, good practice is to use separate keys for signature and for encryption. Thus you need to provide 2 certificates to each client. Also you need to manage client certificates: Issue new certificates when the old ones expire, have a revocation list and organize revocation process.

  • Thank you for taking the time in respond , take into account that in the proposed scheme each client has an unique public key, so if in the initial request for getting the sealed box for that client the client sends his public key for receiving the response ( client sealedbox ) and the server encrypts that pbkey and client token with the client sealedbox there is no way of someone reading the initial response but the original client right?. Authentication is managed with JWT after login Dec 23, 2020 at 10:25
  • If you don't trust the network, then how will you answer these questions: 1) How will clients get server certificate? How will they know that certificate comes not from MIM? 2) How will server know that client certificate contained in the request comes from legitimate client, not from MIM?
    – mentallurg
    Dec 23, 2020 at 13:44
  • I see you’re absolutely right, maybe I could use authentication ( encryption ) for the initial token with a known public key ? The server would have to sign each token and public key of the sealed box Dec 23, 2020 at 14:02
  • How will you make the server public key known to the clients?
    – mentallurg
    Dec 23, 2020 at 14:06
  • Hmm Hard coded in the code of the app or some way of public key exchange between the browser and the server ( the app is an angular app ) Dec 23, 2020 at 14:08

You must log in to answer this question.

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