Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wormhole protocol and PAKE compatibility #71

Closed
anarcat opened this issue Jun 22, 2018 · 19 comments
Closed

wormhole protocol and PAKE compatibility #71

anarcat opened this issue Jun 22, 2018 · 19 comments

Comments

@anarcat
Copy link

anarcat commented Jun 22, 2018

Hi!

I have found with great interest this golang implementation of some of the concepts behind Magic Wormhole. As a user of the latter (and maintainer of the Debian package), I am happy to see other implementations pop up, especially if it means it's easier for others to share files and use those concepts.

Unfortunately, I am concerned with the current implementation of croc, as I explained in #15 (comment)

I see two main issues:

  • compatibility concerns
  • security concerns

Compatibility

While it's great croc reuses some concepts behind magic-wormhole, it doesn't exactly implement the same protocol. This means the problem space is fragmented: a user of croc can't talk with a user of wormhole and vice-versa, which makes it needlessly hard for users to talk to each other.

I understand the idea behind it: a different implementation means more decentralization, for example. But that doesn't mean it has to be a different implementation to be decentralized. Wormhole, out of the box, supports using different relay (e.g. "discovery") and transfer (e.g. "nat trasversal") servers and croc could still implement the wormhole protocol while not being dependent on @warner's infrastructure as a single point of failure (SPOF). In fact, he explicitly said it would be good if other projects would make use of different DNS aliases for those services so they can easily be switched to different backends if traffic would become unmanageable for his services. This is how the debian packages work: the transit server is patched to be tcp:magic-wormhole-transit.debian.net:4001:priority=2.0 instead of the upstream tcp:transit.magic-wormhole.io:4001. Then on Debian's infrastructure, that DNS entry is just a pointer to the normal transit server. The relay server server is the same, however (ws://relay.magic-wormhole.io:4000/v1).

Implementing this would mean adding Wormhole support in croc, specifically the capability of talking with transit and, more importantly, relay servers so that croc would share the same key namespace as Wormhole.

Security

But this would also require reimplementing the key exchange using PAKE instead of the home-grown, SHA256-based key exchanged. As I explained in my previous comments, I am unsure of the security properties of croc as it is done right now. A lot of care was given to the way Wormhole implements the key exchange: it uses a low-entropy ephemeral and weak key to establish a strong session key: that is the PAKE protocol which was published in multiple papers and seems to be solid at the cryptographic layer. I am not sure the SHA256-checksum croc implements has similar properties. For example, does it allow multiple attempts or does it bail on first try? Wouldn't it be possible for an attacker to build a rainbow table of all possible keys and just use that to access the files?

I haven't reviewed croc's security properties in details, so maybe my concerns are misplaced. But as a general principle, rolling out a different cryptosystem for another project seems an idea fraught with dangers that should generally be avoided. In that regard, I also think that PAKE exchange support should be implemented as well as the above network compatibility.

I hope this is useful for you and thanks for working on all of this!

@schollz
Copy link
Owner

schollz commented Jun 22, 2018

@anarcat

As to compatibility with magic-wormhole that was never really a goal for croc. When I started building croc I couldn't find good documentation or source code on how the magic-wormhole relay worked, so I gave up trying to port it.

As to security, you're right that croc is not as secure as magic-wormhole in general. There are several points of vulnerability in a program like this:

  • MITM attacker (between sender/receiver and relay)
  • Evil relay attacker (the relay can try to decrypt things with the knowledge it has)
  • Brute force attacker (someone can spam "code phrases" against the relay trying to trick a sender into sending stuff to them)

AFAIK PAKE will help against MITM and the Evil Relay but not against the Brute force - that is neither can determine the encryption key because that was generated using PAKE between the final recipient and sender. However someone could easily just spam the relay with code phrases hoping to get one right, which is only mitigated by a rate limiter.

I could see that someone could place a MITM in the croc encrypted stream (or a nefarious relay could do this) and they could eventually decode the stream by trying all 5 million possibilities of code phrases. Eventually they could decode it. However, if you use custom code phrases it becomes harder and only the relay could probably decipher it (because the relay has the hash so they could presumably do a rainbow attack). Currently because of the time window for the transfer is so short, I was never really worried about this.

Croc 2.0

I think something better is worth striving for, something that could handle all three such cases.

One thing that comes to mind is a public-private key + code phrase protocol. It would work like this:

  1. A generates public/private key (Apub, Apriv) and sends to the relay a code phrase + Apub.
  2. B generates a public/private key (Bpub,Bpriv) and sends to the relay the same code phrase + Bpub.
  3. The relay tells A that Bpub is interested in downloading the file and asks if thats okay. A says okay.
  4. The relay tells B that Apub will send the file and B says okay.
  5. Once both parties agree, then A encrypts the file against Bpub.

In this case, there is an extra interaction - the sender is asked if they want to send the file to the recipient. That means that brute force attacks won't work because if you have multiple recipients the sender could verify with the recipient what their public key is. Of course this also prevents MITM and nefarious relays because the private keys are never shared, so I believe it is better than PAKE.

@schollz
Copy link
Owner

schollz commented Jun 24, 2018

Public/private key encryption is now added, with double authentication

@schollz schollz closed this as completed Jun 24, 2018
@anarcat
Copy link
Author

anarcat commented Jun 25, 2018

I do not believe this resolves the security concerns I have raised, and it definitely does not add compatibility with wormhole in any shape or form...

@schollz
Copy link
Owner

schollz commented Jun 25, 2018

@anarcat Sorry, compatibility with wormhole was never a goal. I put on the readme that this is "similar in spirit and design" but I really mean similar design and not exact. I'll just remove that altogether.

I think the new changes do address your concerns but I'm happy to hear otherwise. Here's specifically what I thought your concerns were:

For example, does it allow multiple attempts or does it bail on first try?

The transfer is now double-authenticated with user-specific keys. So you can just check with your recipient that you are encrypting for their key. If not, you can bail and nothing is transferred.

Wouldn't it be possible for an attacker to build a rainbow table of all possible keys and just use that to access the files?

This is no longer possible. The data is encrypted using AES-256 with an encryption key that is encrypted with the public key / private key of the recipient / sender. The private keys are never shared so only the recipient can decrypt the data.

An attacker could still try to spam all possible code phrases to to pose as a recipient. However, the sender can easily discover this as the public key of the fake recipient won't match the one of the real recipient they want to send to. AFAIK, this doesn't exist in wormhole. I think that wormhole just subverts this attack by rate-limiting and actually there is no way to guarantee that the recipient is really the true recipient (its basically whoever gets to the code phrase first).

@schollz schollz reopened this Jun 25, 2018
@schollz schollz closed this as completed Jun 27, 2018
@anarcat
Copy link
Author

anarcat commented Jun 27, 2018

How do users check each other's public keys?

@schollz
Copy link
Owner

schollz commented Jun 27, 2018

@anarcat Since this tool assumes there is already have a channel of communication (phone/text) the two parties can just dictate the public key they received to the other person and make sure it matches. This adds a whole other layer of security - in wormhole there is no way to determine if the person who entered the code phrase is the person you actually want receiving the file.

@anarcat
Copy link
Author

anarcat commented Jun 27, 2018 via email

@schollz
Copy link
Owner

schollz commented Jun 27, 2018

@anarcat Short codes are not entirely useless - they serve as a way to first get the two parties into a room together. The uniqueness of the short-code is useful because it helps to make sure the room is unique. The public key validation that is enabled now is sort of an extra layer of protection. If someone else happens to get to that short code first, then the sender would immediately notice that their public key is wrong.

Its possible I guess to just use public keys, but then you'd have to be typing out 30-40 random characters to transfer a file to someone.

Its possible also that the short codes in croc could now be a lot shorter, since there is an another security measure to ensure valid transfers. I'll think about adding this later.

@anarcat
Copy link
Author

anarcat commented Jun 27, 2018

I think the short codes add a false sense of security. You end up being completely vulnerable to a hostile server or MITM attack because PAKE is not implemented correctly (or at all, in fact). From what I gather, croc simply exchanges unsigned public keys over an insecure channel and tell users they are to be trusted yet provide no way of doing so in the protocol and leave that to a full, out of band fingerprint check. The whole point of PAKE's short codes is to fix the problem of such fingerprint checks that do not work for humans.

I am sorry, but I do not believe croc brings the sort of security guarantees it says it does, but I am not sure I have the energy to convince you so. I hope others will be able to make a better argument than me! :)

Have a nice day...

@schollz
Copy link
Owner

schollz commented Jun 27, 2018

@anarcat You're right that PAKE is not implemented at all, it was never my goal or intention.

In fact, public/private keys actually provide more security than PAKE - in addition to encrypting the file for a single recipient they also provide a means to authenticate the recipient (wormhole cannot do this - anyone with a code phrase could receive the file! There is no stopping someone guessing code phrases until they get it right).

Key signing here is unnecessary, because the public key is authenticated by the source (the person who generated it) over the channel of communication that is already open between the two people (i.e. the phone/text). I.e. you can just tell someone your public key and see if matches. Public/private keys, by their nature, assures that the public key corresponds only to one private key, which cannot be generated by a MITM, and only exists on the recipient machine.

I'm sorry you don't want to continue the discussion. Thanks for prompting this idea of improving security though, which I think is a great addition to croc.

@anarcat
Copy link
Author

anarcat commented Jun 27, 2018 via email

@schollz
Copy link
Owner

schollz commented Jun 27, 2018

@anarcat Could you explain something that I don't get - how does wormhole+PAKE stop an evil relay?

Here's an evil relay scenario. The short code is easy to guess. Say A wants to send to B through the relay. A generates a code phrase. When A connects to the relay, the relay could pose as B and try all known code phrases, and eventually gets the one A used. A is totally unaware of the attempts until the right attempt is made. Thus the PAKE interaction occurs between A and the relay. Then the relay can pose as A when B tries to get the file, and they can transfer the file to them now using the same code phrase. In this way, the relay gains access to the file and allows the file transfer to go through.

The wormhole says that there is only one guess at a time. Does this mean that the wormhole relay only allows a single transfer to happen a time?

@anarcat
Copy link
Author

anarcat commented Jun 27, 2018 via email

@schollz
Copy link
Owner

schollz commented Jun 27, 2018

@anarcat Okay, the channels makes everything make sense to me now.

I think I'll write a croc3.0 to use PAKE. I do like public keys, but I like the simplicity of just using the code phrase.

Thanks for continuing the conversation!

@anarcat
Copy link
Author

anarcat commented Jun 27, 2018 via email

@schollz
Copy link
Owner

schollz commented Jul 3, 2018

@anarcat I've looked into wormhole compatibility. It would be great, but its very complicated. I'm going to get in touch with the author for more details.

In the meantime I've bumped croc to 3.0 which uses PAKE: https://github.com/schollz/pake

@anarcat
Copy link
Author

anarcat commented Jul 4, 2018 via email

@vu3rdd
Copy link

vu3rdd commented Dec 12, 2018

fwiw, there is a spake2 implementation in Go available here: https://salsa.debian.org/vasudev/gospake2, that might save you some time than coming up with your own spake2 implementation.

@schollz
Copy link
Owner

schollz commented Dec 15, 2018

Thanks @vu3rdd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants