hackmdio / codimd

CodiMD - Realtime collaborative markdown notes on all platforms.
https://hackmd.io/c/codimd-documentation
GNU Affero General Public License v3.0
9.25k stars 1.05k forks source link

Support end to end encryption #138

Open janniklorenz opened 8 years ago

janniklorenz commented 8 years ago

What do you think about supporting end to end encryption for all notes?

The URLs are already to long to remember, so we could just add a client generated symmetric key to encrypt the note. I'm currently not sure about the syncing process with encrypted data, do you have an idea how this would theoretically work?

jackycute commented 8 years ago

Hi @janniklorenz Actually we already using compression algorithm on every data storage and transfer (notes, operations, revisions). So data are not plain-text in anywhere, further more will be security.

If you want to encrypt the data and based on user's key, that might affect the performance (but very safe).

Theoretically process is, the user own a private key and we own a public key (which are symmetric), on every data we transfer to the user will encrypted with that user's public key first and the user decrypt the data with its private key.

  1. generate private and register to server (SHA-1 or SHA-256)
  2. server generate the public based on its private key and save to DB
  3. server send data to user which encrypted with user's public key
  4. user receive the data and decrypt with private key
janniklorenz commented 8 years ago

Yes, you are right, I only thought about the process as a guest, not as a registered user. The goal I wanted to archive is, that the server can't access the content of the notes.

The easies solution in my opinion would be, to use symmetric encryption. We could just add the key to the note url as a GET parameter. So each client can encrypt/ decrypt the operations with it.

We might get problems applying the operational transformations, when we can't read the content of the document on the server.

jackycute commented 8 years ago

@janniklorenz That is a huge problem. The server should be able to read the content, or it can't hold OT and make revision with patches. Why do you worry about the server can access the content? If server is not trusted, nobody could be.

janniklorenz commented 8 years ago

I see the problem with applying the OTs, maybe we can perform these actions on one authorized client, and just use the server to share the complete document. Latency would be our main problem here.

jackycute commented 8 years ago

In our very early version, we've using the compute result from every client. I can tell you that client even more can't trust at all.

As long as anyone who own both content and keys will be able to decrypt the content. So inevitable the server can access the content.

The idea you're talking about is decentralize, which you might interest to Merkle DAG and hyperlog. There is no other way I know can only allow user to access without a stable server besides decentralize network. And that's mean the content itself is encrypted with certain algorithm that already imply some metadata which might indicate the owners and permission.

jackycute commented 8 years ago

@janniklorenz Hey bro, your proposal is still cool :smile: I personally hoping this can be achieve because this will be very secure. So we'll keep thinking about it, maybe there will be a solution someday and will let you know.

jackycute commented 7 years ago

Hi @janniklorenz https://github.com/standardnotes/collab-editor Above is a really cool and awesome example for this.

janniklorenz commented 7 years ago

Thanks, I will take a look.

gabemarshall commented 6 years ago

Just wanted to add to this by saying I also would love to see e2e encryption support - even if it was an optional feature that required losing version history.

Similar to what @janniklorenz mentioned, the symmetric key could be passed via the uri hash (not a query parameter in order to avoid sending it in the actual HTTP request) and possibly encrypt/decrypt everything on the client side with something like aesjs ? Or maybe store the key temporarily in localStorage?

SISheogorath commented 6 years ago

Okay, after some thinking about that, I think there is a theoretical possibility to implement that. End2end encryption using symmetric encryption like AES can be done on OT operations, BUT you need to use a block-mode like CTR. There is no easy way (means without removing the servers from the OT part) to do this with CBC or similar.

And you probably need to rewrite the entire wiring part between OT and CodeMirror.

I really like the idea of having notes end2end encrypted but I know for sure that we don't have the development resources for that feature around. As there are various problems that are way higher prioritized. So if you want to go and implement it yourself, you are very welcome! But from the maintainer side it's currently not possible to implement this from a time and money perspective.

On 04/11/2018 08:17 PM, Gabe Marshall wrote:

Just wanted to add to this by saying I also would love to see e2e encryption support - even if it was an optional feature that required losing version history.

Similar to what @janniklorenz mentioned, the symmetric key could be passed via the uri hash (not a query parameter in order to avoid sending it in the actual HTTP request) and possibly encrypt/decrypt everything on the client side with something like aesjs ? Or maybe store the key temporarily in localStorage?

-- Signed Sheogorath

ccoenen commented 6 years ago

I don't think this makes much sense, I'm afraid.

You are trusting a server in any case. Either, you're trusting that nobody will look into the database (current model), or you'll be trusting that the server won't give you wonky JavaScript (which you will probably not be able to verify).

In case the server owner wants your secret document, they'll just deliver a version of the javascript bundle that somehow exfiltrates the secret encryption hash. And what's worse: you get the false sense of security that it could never be read by anyone.

ccoenen commented 6 years ago

This would be less of an issue, if people could somehow bring their own clients and just connect to a server (think email with gpg), where you can reasonably be sure that the program you're running right now is still the same you were running yesterday. And where you're also getting the program updates from a completely different party (most of the time with signatures, verifying that you don't get a MITM attacked version of the application).

All of this is not easily possible in our case.

SISheogorath commented 6 years ago

Agreed.

In my originally write up, I was also referring to this problem. But it turns out to be a very unpractical point of view to the problem, as it actually describes different problems.

end2end encryption itself, can "future security". So that when you leave a service and the server admin or owner turns on you, changes, … and you decide to no longer use this service, there is no way to get the data back from you even when there are backups.

So solving the MITM problem for the web application is actually a different one from using end2end encryption in general.


But yes, in general I agree that this is of course a problem, that makes end2end encryption way less worthy.

On 04/11/2018 09:51 PM, Claudius Coenen wrote:

This would be less of an issue, if people could somehow bring their own clients and just connect to a server (think email with gpg), where you can reasonably be sure that the program you're running right now is still the same you were running yesterday. And where you're also getting the program updates from a completely different party (most of the time with signatures, verifying that you don't get a MITM attacked version of the application).

All of this is not easily possible in our case.

-- Signed Sheogorath

gabemarshall commented 6 years ago

Re: Server deliverying wonky JavaScript - subresource integrity could help with that, but fair point - the bring your own client model would be better.

Didn’t mean to stir up an old issue, I honestly just stumbled upon hackmd today and got a little too excited :)

SISheogorath commented 6 years ago

No worries about subresource integrity, we already do that.

But the problem is this doesn't help against a bad server administrator.

On 12 April 2018 05:37:50 GMT+02:00, Gabe Marshall notifications@github.com wrote:

Re: Server deliverying wonky JavaScript - subresource integrity could help with that, but fair point - the bring your own client model would be better.

Didn’t mean to stir up an old issue, I honestly just stumbled upon hackmd today and got a little too excited :)

-- Signed Sheogorath

Sent from my Android device with K-9 Mail. Please excuse my brevity.

gabemarshall commented 6 years ago

True.. I neglected to realize that subresource integrity wouldn't prevent the "bad admin" from just changing the response body. I suppose I should look at how apps like Wire that use the Signal protocol to implement e2e within web apps before pursuing this further.

Thanks!

SISheogorath commented 6 years ago

Even Wire and Signal (which provides an electron app) won't help you. The problem with the "bad admin" is that the app itself is delivered by the server and there is no way to verify that it's the same as yesterday.

By "bad admin" we refer to the administrator of the HackMD server that sends the application to you. We don't talk about a administrator in a local environment that has no access to the HackMD server.

The point is: The Server sends you the application and has this way has full access to the encryption logic and this way to compromise the entire end2end encryption. The only way to mitigate that is to provide an offline installable application that doesn't change until you want it to change (like updates, …).

gabemarshall commented 6 years ago

I haven't looked into it yet, but CryptPad seems to have found a way to implement secure collaborative notes.

rmst commented 6 years ago

One solution would be to make official Chrome and Firefox browser plugins (and potentially Mobile web apps) that thinly wrap the client code. If the plugin / app is installed the user could read/write encrypted if not encrypted notebooks wouldn't be available (the encryption key would be stored in the plugin storage)

Edit: Also, shouldn't this issue be reopened? That would make it easier to find and the discussion and referenced issues here look like people are interested.