2

Background

We are an API provider. We are unifying 3rd party messengers where we can't control the client app.

What we need

Even though we need to provide the 3rd party messengers with the unencrypted message we would like to prevent ourselves from reading the content of messages sent via our API in both directions as much as possible.

The process of sending/receiving messages with 3rd parties

Sending a message to client have this process:

  1. Client sends a message {content: "Hello!"} to us.
  2. We will process the message.
  3. We send it to a 3rd party.

Partial solution

I am not able to find a satisfiable solution but maybe I'm missing just a last piece. Messages in the logs and database will be encrypted. This a scenario I came up with:

  1. Client sends an encrypted message {content: "f8239jflads8"}
  2. We will process the message.
  3. Just before sending to a 3rd party, we will SOMEHOW GET THE KEY and decrypt the message.
  4. We will send the message {content: "Hello!"} to a 3rd party.

Questions

  1. Is there another solution?
  2. Is it possible to secure the decryption key so that users are safe OR at least safer? E.g. by limiting who can see the decryption keys so that nobody from our company can decrypt the messages from logs or database?
  • 2
    What about generating a client side key at each app startup. Messages are encrypted using this key, sent to your servers, Your servers get the key for a single use, you decrypt and send the plaintext to the 3d party service. If your client's app crashes/restarts... the pending(unsent) messages could not be sent. – Soufiane Tahiri Feb 25 at 13:11
  • "... when we need decrepted text to be sent to the 3rd parties?" - if this is an actual requirement that you need to decrypt the text then this collides with your requirement to have end-to-end encryption. Please explain if this is an actual requirement or that it is just a feature of your idea to implement the chat and that you would rather not have such decryption be done by your system (i.e. only encryption in sender and decryption in recipient but not in your forwarding system). – Steffen Ullrich Feb 25 at 17:16
  • @SteffenUllrich The client app will be for example a Facebook Messenger app installed on mobile. There is no way that clients can decrypt messages. For this very reason we need to send messages to Facebook API as plain text. I'm aware that it will not be an e2ee. – Amio.io Feb 25 at 17:28
  • @SoufianeTahiri We don't have a client app. The 3rd parties like Facebook have it. How would you pass the decryption key to our servers? By providing an API where we would ask for it? How can we do it so that it's not the infamous security by obscurity? – Amio.io Feb 25 at 17:34
  • 1
    @Amio.io: I've deleted everything from your question regarding your own chat and its end-to-end encryption since this was completely irrelevant to what you actually wanted to know and just made the question very confusing. – Steffen Ullrich Feb 26 at 7:35
1

One way to do this is to have the client app (which must already have the message in plaintext) send the message to the third party chat system directly instead of through your system. Depending on how you authenticate with the third party, this may mean that you'll have to disclose your API key to the client or provision a unique API key for each client users and somehow restrict their permissions.

Alternatively, if you authenticate with the third party app using an algorithm like HMAC, you may be able to split the HMAC calculation into two. The client app should calculate a hash of the plain text message, send the hash to your server, which should then calculate the authenticated hash from the given hash and your API signing key. The client then can make a connection to the third party server (possibly proxied through your server if there are IP address restrictions) and send the authenticated hash and the plaintext message using your credential without disclosing the content of the message to your server. This is a form of blind signing. However, you need to be careful with this as blind signing means that you also have no control over what you're signing and it may be possible for a malicious client to construct message that allows them to do things they shouldn't if your API signing key have greater privilege than what the client is supposed to have.

  • The best way for our customers would be if we made our solution on-premise (installed on their servers). It's what you describe in the 1st part but to the extreme. As to the 2nd part, unfortunately, it's not a solution for us because we need to decorate the data or use it for analytics. – Amio.io Feb 27 at 8:47
1

Let's say your client sends you:

{
   "content": "EncryptedMessage!",
   "defaultKey": {
   "passphrase": "DecryptionKey",
   "clientIdentifier":"clientIdKey"
  }
}

The defaultKey is something you can validate but you cannot determinate or guess, it's something unique that can be generated on install time, up to you to consider adding/implementing a GenerateKeys(), Encrypt() , Decrypt() functions.

All you have to do at this point is to process the content with defaultKey.passphrase before sending it back to a 3d party.

To keep logs, you can keep track (on db?) of clientIdKey and encrypted content. The clientIdKey is tied to a unique client and cannot be used to decrypt the content.

  • I like this idea a lot! :) The clients could encrypt every content with a different key every time. We would not store the passphrase and would not log it either. – Amio.io Feb 26 at 13:52
  • Nice to hear this :) – Soufiane Tahiri Feb 26 at 14:39
  • What's the point of sending the decryption key with the message itself? If you just want to log something to keep track of message sending, you can just hash the message then log the hash. – Lie Ryan Feb 27 at 10:33
  • euh..maybe to decrypt the message before forwarding it to a 3d party ? – Soufiane Tahiri Feb 27 at 10:54

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.