0

I want to build a webapp and a sister mobile app (using react native) that uses client side encryption. The encryption would be for text entries written on a daily basis that the user could create and edit. If the user goes offline, I want them to still be able to edit entries currently on their device and to create new entries, and I want those edits to be pushed to the server when the user comes back online.

If the user enters text offline for a particular day on one device, then forgets and enters different text offline on another device for the same day, I'd like the two entries to be merged into one entry when the devices go back online. Is there any sort of magic that would allow me to do that on the server with the encrypted files?

If not, I'd have the devices send a hash of the encrypted text as it was before the edits. When the updated text hits the server, I would send the hash along and compare it to the hash of the encrypted text that was currently stored. When the second update comes, the hash would not match the stored text, and the stored text would be sent back to the client to be reconciled. Are there existing protocols/libraries out there for this sort of thing? I'd rather not reinvent the wheel.

1

Let my rephrase your preconditions:

  • All data stored at the server or transferred to the server are encrypted.
  • The encryption key is only known to the clients.
  • There can be multiple clients, all use the same encryption key or some key derived from a shared secret. How this key/secret is shared between clients is outside of your question.

Then you are assuming that two clients might edit the same data and ask for a way to merge these edits at the server side.

First, it is unclear what the result of this merge should be in your opinion even if the data are not encrypted. Therefore I'm simply assuming that you can somehow split the data into independent parts (like sentences or paragraphs) and treat these parts as fully independent entities when merging, i.e.:

  • If both clients have edited different parts just make each client replace this part only. Similarly you can detect and resolve if both clients have added new parts at different places or if one removed a part which the other did not touch.
  • If both clients have conflicting edits on the same part someone would need to resolve the conflict. This could be done that the first edit wins (i.e. you need timestamps) or that you ask for manual conflict resolving.

Note that with above merging algorithm there is no need to actually look at the contents of the parts, i.e. the algorithm could be executed on plain text, on hashes of the parts and also on encrypted parts if all parts were encrypted independently from each other. Only the manual conflict resolution would need to somehow present the contents to the user so that he is able see what he is actually resolving. But since all clients share the same key/secret each clients could also decrypt any part encrypted by the other client and display it within the manual conflict resolving.

In other words: how the merge is done can be made independent from the data being encrypted simply by splitting the data into independent parts (which you would need for merging anyway) and then encrypting each part individually and independent of the others. The exact implementation, libraries etc to do the merge are thus not a problem of information security anymore and thus would be off-topic here.

  • Thanks for the response. I was hoping there was some established library/protocol that could handle the details of merging the text that might also deal with encryption, but if not, breaking things into sentences makes sense. If I encrypt each sentence individually, would short repeated sentences be more guessable? If one big encrypted chunk would be significantly more secure, I might want to always do merging on the client since there would often be manual conflict resolution anyway (I think it'd be slower that way, but I don't think it'd be that noticeable). – Loktopus May 21 '18 at 15:16
  • 1
    @Loktopus: if you always use a random IV for encryption it should not matter if the parts are short or not or if anything gets repeated. You could in theory even encrypt each character separately which of course has lot of overhead. I recommend that you search for phrases like "operational transformation" to get to the algorithms. If you combine this with "collaborative editing" and "client side encryption" you might end up with a description of cryptpad which looks similar to what you want achieve by your own. – Steffen Ullrich May 21 '18 at 15:47
  • Cryptpad was an awesome thing to point to, thanks. Chainpad (part of cryptpad) looks exactly like what I wanted. – Loktopus May 22 '18 at 20:09

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.