trystero icon indicating copy to clipboard operation
trystero copied to clipboard

Session descriptor signing and verification support

Open expenses opened this issue 2 years ago • 4 comments

~~Hi! I just found this project recently and it seems super useful. The symmetric encryption scheme mentioned in https://github.com/dmotz/trystero#encryption looks very nice for preventing MITM attacks when the room password is private. However, I'm looking into building a system with public rooms, so the symmetric encryption is not viable for me. What I'd like is a scheme where each peer generated a public/private keypair and uses that to encrypt the SDPs, like what SaltyRTC does except decentralized (https://saltyrtc.org).~~

~~When a new peer B is found, peer A would need to encrypt it's SDP offer with peer B's public key. Peer B would then decrypt the SDP, make an answer and encrypt it with peer A's public key, sending it back. These public keys could either be gossipped or known in advance.~~

~~How possible is it for something like this to be implemented? I don't know a lot about how the BitTorrent tracker websocket works. Would it allow sending messages like this?~~

Edit: I'm re-opening this as support for session descriptor signing. See https://github.com/dmotz/trystero/issues/19#issuecomment-1113961538.

expenses avatar Apr 28 '22 14:04 expenses

Sigh My thinking was pretty pidgeon-holed when I wrote this. Trying to prevent a MITM for a public server is unnecessary because it's just that; public! If someone wanted to snoop on conversations they'd just connect normally. There is a benefit to having everyone generation public/private keypairs which is that you can verify their identity by having them sign a nouce, but this can be implemented as a layer on top of this library. There's a small benefit to having asymmetric encryption for private rooms, but it's minor enough that I don't think it's worth adding. I'll close this issue now.

expenses avatar Apr 28 '22 16:04 expenses

Yeah the encryption feature in Trystero is for a pretty limited use case. The idea was that a public medium operator (e.g. someone running a torrent tracker) can see the plaintext SDPs and then potentially peer with anybody by sending an answer, so a Trystero-based app can add a symmetric key to prevent that. Symmetric keys of course rely on some shared secret that must be communicated or known by other means, so the canonical use case might be something like a chat app where a password is shared via URL query string. In the end users are still anonymous and there is no verified identity via any of this.

I anticipate Trystero users will build their own asymmetric authentication solutions on top that work post-peering, but I've been considering adding an easy/agnostic way to verify/reject a peer from the room via some predicate function you can pass to the library. In this function you could do something like a challenge signing like you mention. Would this be useful/interesting for your use case?

dmotz avatar Apr 29 '22 21:04 dmotz

So the challenge signing method I mentioned doesn't actually prevent MITM, because the MITM can forward the challenge and response between the two parties and take over from there. However, I have come up with a much better solution, which is to key-sign the session descriptors. I've implemented this in a (WIP) branch here: https://github.com/dmotz/trystero/compare/main...expenses:key-signing.

Essentially, you bundle a public key and a signature along with the session descriptor blob (I'm just going to call them SDPs even if that isn't technically accurate). This slightly increases the size of the data sent to the tracker, but only maybe by 50% because ECDSA keys are quite small. You then verify the SDP with the key, making sure you don't connect to the peer if it isn't valid. Finally you add the key to the Peer object and pass it to onPeerJoin (we could probably do this another way) so that a user of the library can pull out the key and know who they're connected to (See https://github.com/expenses/webxr-pbr/blob/451a8964412c6960b594f2ddc119a0634ee9e260/web/index.html#L67-L94).

This doesn't stop a MITM from removing the signature and re-signing or replacing the SDP, but no matter what, if a SDP is signed by a key you recognize then you know it's really them.

I'll try and tidy up the branch a bit more. Let me know if you're open to merging it!

expenses avatar Apr 30 '22 10:04 expenses

If we figure it it how to recover the public key from the signature (see https://github.com/diafygi/webcrypto-examples/issues/37) then we could further reduce the data that's sent to the tracker.

expenses avatar May 02 '22 12:05 expenses