This project made me learn about and attempt to implement the SPAKE2 protocol and HKDF as an exercise.
It's quite fascinating. It lets you upgrade a short password to a long key, but requires trusting a server to rate limit attempts on brute-forcing that short password. It seems difficult to find a practical use case for it tho. Because it's only relevant when it is impractical to send a long key. But if you think for a second, lets say you are transferring from a desktop to a phone, you can show a QR code and scan in with your phones camera, thus achieving a secure handshake bypassing the need for SPAKE2 all together. Maybe it would defeat the simplicity of the tool, but if it also provided a long string of words for the key, a user could optionally send all the words instead of just the first few and get themselves a secure key without needing to trust the server.
> requires trusting a server to rate limit attempts on brute-forcing that short password
This isn't true. Particularly, if an attacker attempts to connect with the wrong password, this will be seen by the client, which then aborts the connection. So an attacker can only try one password. You can test this yourself:
A: $ wormhole send foobar
A: Wormhole code is 1-whimsical-klaxon
B: $ wormhole receive 1-klaxon-whimsical # wrong password
B: ERROR: Key confirmation failed. Either you or your correspondent
B: typed the code wrong, or a would-be man-in-the-middle attacker guessed
B: incorrectly. Try sending the file again.
B: <exit>
A: ERROR: Key confirmation failed. Either you or your correspondent
A: typed the code wrong, or a would-be man-in-the-middle attacker guessed
A: incorrectly. Try sending the file again.
A: <exit>
So if you receive this error (potentially repeatedly), you learn that there is an attacker trying to guess passwords. You can then choose to increase code length or simply stop using that channel.
The CLI also has an option to further mitigate MITM attacks with the `--verify` flag -- this shows to both clients a hash of the transcript, which can be verbally verified before proceeding with the transfer. This allows detecting an attack even if the attacker gets the password right on the first try (which has probability 1/65536).
Does that mean if 100 people send files over a server, and out of the 100 recipients a single one spells the code wrong, all 100 transfers get cancelled?
No, the key negotiation occurs between two clients.
In the Magic Wormhole protocol, the number at the beginning of the Magic Wormhole phrase specifies a "nameplate" used to negotiate the "mailbox" which both clients (sender and receiver) use. If a recipient specifies a _matching_ nameplate but a _non-matching_ key phrase, the file transfer transaction between the sender and receiver with a matching nameplate will fail (since they cannot correctly produce a shared key), but nobody else is affected in any way.
An evil attacker could DoS the magic-wormhole mailbox server by spamming mailbox nameplates with bad keys, since there isn't much entropy at all there, but they would affect only single transactions at a time.
That's all nice and dandy, but what about sending data the other way, from a phone to a desktop? Meticulously typing in long strings of text with no mistakes is not really a practical solution for the vast majority of users.
Localsend, if you're on the same wifi network. Works decently for sending files between Android/iOS/Desktop (sometimes on iOS the app must be closed and reopened a couple of times before non iOS devices can detect it, for some reason).
I use magic wormhole everywhere else, servers, vms, etc.
You can still generate the QR code in the desktop and scan it with your phone camera. The device receiving the file does not have to be the device that scans the code.
Maybe if your camera is broken? Or you are using one of those phones built without a camera (like the ones issued to people who work at secure government sites)?