The goal of this post is that the security experts out there find flaws in our design so we could improve the security of KDE Connect, which is an important point. Probably this will get too technical if you don’t know what RSA keys are, so proceed under your own responsibility .
The first thing we need in KDE Connect is the discovery of other devices. At the moment we provide a single backend that uses network UDP broadcast to achieve this. When a devices connects to a new network, it sends a broadcast message with its unique ID and name and how reach it (that is: ip and port). Other devices will react to that broadcast sending back their own information, so both devices will know each other. (Note: We tried Avahi instead of a manual UDP broadcast, but finally we didn’t use it because we found two main problems: the Android implementation is of extreme poor quality, plus multicast is sometimes blocked by routers ).
At this point the devices can ‘talk’ between them, but they don’t trust each other until the intervention of the user, so they will discard any incoming package that is not a pairing request. Each device has a unique pair of RSA public and private keys, when the user decides to start the pairing process from a device, that device sends its public key to the other device. If the other device accepts the pairing (it will show a message to the user with a timeout asking to do so), it will send back its own public key, so now both devices will be able to send encrypted packages (using their peer’s public key) to each other, that only the expected recipient will be able to read.
Note that the public key can easily be retrieved from a device, just by starting the pairing process with it. So only with that key and the device ID (also public) you would be able to fake a device and send encrypted packages to any other in its name (even though you would not be able to decrypt the answer, since you don’t have the private key of the device you are faking). To solve this issue, we will require a both-way encrypted handshaking (which is not implemented yet):
- Device 1 sends some random number encrypted with Device 2′s key
- Device 2 decrypts the number and encrypts it again with Device 1 public key
- Device 1 decrypts the number and checks it is the same it originally sent (so Device 2 have the correct private key to decrypt it).
- The same happens swapping Device 1 and Device 2
Do you think that the security this provides is enough or are we missing something? Would be better to have a different pair of public/private key for each device, instead of a single one?
Thank you all and happy hacking!