Copied from bountysource (https://www.bountysource.com/issues/1474343-support-for-file-encryption-e-g-non-trusted-servers). Check out the source code here: https://github.com/Lennix/syncthing
Hey guys,
I’ve been working on this about a week now and it’s working quite well. Let me tell you how to set it up:
#Setup
On your client you add a new folder like usually, but check the “Encrypt” box on the lower left. A random generated 32 byte (256bit) passphrase will appear and you should write it down or save it somewhere safe. You can change that passphrase to use your own (please only 32 bytes) or enter your old passphrase to recover a folder. On the receiver (I call it the eNode) you also add a new folder, but now you check the “Encrypted” button.
After adding the folders, the synchronisation should start and you should see your encrypted files on the eNode. If it doesn’t start directly, you can restart syncthing to let it reload the config, that seems to be the problem most of the time.
I encourage you to test this. Please backup your old database and config and add new folders instead of changing the config of your old ones.
And now some technical stuff:
#Encryption details:
The encryption used is AES-256 (CFB-mode) with a pbkdf2 derived key using the passphrase and the block hash as salt. Files are encrypted directly on the sending client and no encryption information is shared with the eNode.
#Changes to syncthing / technical details:
The client sends the folder index containing the (SHA256) hashes of the files to the eNode. The eNode then requests the files from the client, which sends them after encryption. At the moment no hashes of the encrypted files are shared, so we’re relying on the underlying protocol for checksumming. On an index update we can request the blocks changed since we have the hashes of the cleartext files. We can also copy already received blocks from other files. The eNode itself does not scan the file system since it will generate different hashes.
#Limitations / ToDo:
- Currently folder and file names are still cleartext on the eNode.
- Sending files from multiple clients is experiemental right now. But it’s paramount that you connect the encrypting client ONLY to the enode. Not to another encrypting client. (You could do that by adding the same folder another time without the “Encrypt” option set.
- The key salt used is based on the block.hash. That has 2 drawbacks: 1. it’s not truely random 2. if both databases get destroyed the files are not recoverable.
#Some history: I first started using RSA OAEP encrypting using the public/private keys generated by syncthing. Due to that encrypted blocks were bigger than clear text blocks giving me a big headache. After all that was resolved I had to realize that RSA was way to slow for this kind of application. On an i7 4770k with 100% CPU utilization I had about 50-100kB/s decrypting the files. After that I had to change my plans and stick to a symmetric chiffre and since AES-256 is well known and implemted I chose that. Using a salted key I could also drop the IV from the encryption resulting in same sized blocks. That way I could re-enable a lot of features syncthing already had.
And here we are. Please look at my code critically. I haven’t written tests yet. Maybe you have feedback on my implementation or are looking for another feature.
If you have questions you can also hit me up on twitter: @pknede