How to implement search functionality of messages in a chat when using end-to-end encryption?

892 views Asked by At

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).

0

There are 0 answers