chr15m / bugout

Back end web app services over WebRTC.
https://chr15m.github.io/bugout
MIT License
607 stars 59 forks source link

Ability to use a shared secret key to encrypt traffic between peers #10

Open chr15m opened 5 years ago

pwFoo commented 5 years ago

Would be interesting for group chats to exchange a shared secret via e2e / p2p encrypted connection?

Group chat part could be take care about exchange and update secret for "rooms" to all room / group members.

So both should work side by side and use encryption type as needed?

chr15m commented 5 years ago

Yes and it could be accomplished after #10 is implemented.

rfestag commented 4 years ago

I haven't delved too far into the code, but I'm curious: why can't messages be encrypted even when "broadcast" use the key pair? I'm assuming that either each client has a connection to all other peers (in which case it is already sending individual messages to each peer and can encrypt each message), or the "server" is acting as a hub and routing to clients. In either case, the message would have to be sent N times (once to each peer), and could each be encrypted for that peer. Is it just a concern over that being wasteful (N encryptions vs. one encryption and N sends)?

chr15m commented 4 years ago

@rfestag the "connection to all other peers" part can be flaky and that's why there is a gossip protocol to spread messages over the network of peers by retransmission. The basic problem is that the encryption pubkey of all peers might not be known to the sending peer at send time. I would be open to adding this as a flag or alternative send method for cases where you definitely only want to send to peers you've already seen.

rfestag commented 4 years ago

Gotcha, makes sense. Do you have documentation or a description somewhere of the gossip protocol you're using? Also, as I think this through, the only use case I see this being useful for is multicast - that is, where in a given gossip network, you want to send a message to a subset of the participants, and for that message to be encrypted. Is that right? I say this because:

  1. If I am sending a broadcast, all members of the network are permitted to see it. So there is no confidentiality issue with the message (each node is already allowed to see it), so no value in encrypting it at the application layer.
  2. WebRTC already provides encryption between two peers, so you have the data encrypted in flight between nodes.
chr15m commented 4 years ago

That's exactly the use-case I had in mind. For example when you want to set up a "group chat" type of situation where everybody in the group has the shared secret. You can even derive the shared secret from something inherent to the group, depending on the application.

rfestag commented 4 years ago

Makes sense. In that case, is there a reason it wouldn't make more sense for that multicast group to simply form a separate broadcast network (i.e., I create a group chat by starting a new Bugout server with an address we all know, and offering it to whoever I want to join). They seem to both do the same basic thing, but creating a new network means only members of the chat will potentially pass the message between each other (so, the message itself never would be routed to somebody who shouldn't see it in the first place). I see a few advantages

  1. It obviates the need for a shared secret (reducing complexity in Bugout)
  2. It potentially reduces the latency for any message. The message will only ever go through intended recipients, vs. potentially routing through nodes that don't need it or care about it.

I guess I don't really like the shared secret because there doesn't seem to be a good way to share the secret that is any better than sharing the URL (which effectively serves as the secret at that point). Either you negotiate the secret by direct messaging, or you negotiate the new URL via direct messaging (same effective problem). If you are going to create a chat room for people to just connect to directly, it seems like you'd be better off just implementing an authentication mechanism.

What could be interesting though (which would probably be a different feature request) would be for GPG support (or at least something like it, where you can have certificates with de-centralized trust). In the chat app example with rooms, it would ensure that people joining are trusted by room participants to be who they say they are (in case they happen to get a valid URL to join a room they weren't intended to). Some sort of authentication mechanism at a lower level (say, only allowing peers that are trusted to join) seems more broadly useful than a shared secret for broadcast.

chr15m commented 4 years ago

Because of the way the WebTorrent peering works, it is far simpler and more secure to delineate groups of peers by a shared secret than it would be to try and exclude potentially unwanted peers by obscurity. Room names (or more correctly, their hashes) are effectively public knowledge because of the way the WebRTC signaling is accomplished and this basically means anybody can join a given group of peers. The only way to be sure you are communicating with a subset of nodes you want to communicate with is using cryptography.

GPG support is out of scope but could be implemented on top of Bugout.

draeder commented 2 years ago

As a note, I built an extension that encrypts Bugout broadcast traffic for already seen peers. It's based on Gun's SEA suite. It also adds SEA encryption for direct messages on top of the NaCL encryption Bugout is already using. I'm curious about the use-case of peers not yet seen.. I am just getting into unit testing and will see what happens with my extension for that use case.