2

If I add end-to-end encryption to a chat app I have written, I would not be able to read the contents of the exchanged messages server-side, so if I want to retain the message search functionality I would need to implement it in another way.

What would be the correct best practice?

I thought about the following possibilities:

  1. Storing a local DB (e.g. SQLite) on each device where the messages would be stored in unencrypted format.

    This has some disadvantages though: beside the fact that the messages are stored unencrypted, the app is accessible via web browser as well, and in this case I cannot store whole conversations in the browser's session storage (I don't even think that they will fit).

    Also, this way I don't have a unique source of truth anymore (have to deal with the server-side DB storing the encrypted messages as well as the local "device-side" SQLite DB for the unencrypted ones).

    So this is not a viable path, I think.

  2. On the client (being it a web browser or a device), when the user performs a search in a chat, download all the messages for that chat, decrypt them all and then perform in-memory search.

    Downside: I have to download all the chat history in order to perform a search. If a chat has a long history, chances are that all data won't fit into memory. Once the history is downloaded, I can store it in-memory until the user either reloads the page (if using a web browser) or kills and restarts the application (if using a device like a smartphone or tablet).

    Pros: I can show the number of messages where the search term was found.

  3. Same as 2, but I will perform multiple requests to the server, each fetching only a small portion of the messages of a chat, e.g. when a user searches for "foo", initially I will ask the server for the last 30 messages, decrypt them on the client, search for "foo", show the results and the count of the messages containing "foo" in this chunk only and when the user scrolls or presses a "Search more" button, perform another request which would fetch another chunk of 30 messages, add these to the results and increment the count of the matching messages after taking this nth chunk into account as well.

    Downside: I cannot show the overall count of matching messages upon the first search.

  4. Anything else? Maybe an even better solution which is also used by other services like Telegram or WhatsApp (I know both implement end-to-end encryption for their chats).

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
tonix
  • 6,671
  • 13
  • 75
  • 136
  • A good secret message is the one that is deleted after reading. Why do you keep messages on the server? Be like Signal, the users get the encrypted message and delete it from the server. The user decides that they can keep the messages and search over what is left. – kelalaka Oct 17 '20 at 16:00
  • Thank you for your comment @kelalaka. I wasn't aware of how Signal handles this. That would be another feature to implement, and at that point the server would only act as a gateway/stateless message router. But the point is, how does e.g. Telegram or Whatsapp or even Signal implement message search functionality provided that all three encrypt messages using end-to-end encryption? – tonix Oct 17 '20 at 17:47
  • 1
    It is performed on the client-side on whatever left! There are a scheme that enables search over encrypted data, however, not a good idea to use on the server since it leaks information on the return results... – kelalaka Oct 17 '20 at 17:49

0 Answers0