Seeking recommendation to secure packets sent over internet

Hello,

I am looking for a way (lib) to encrypt data sent over internet.
The endgoal is to have a server/client to server/client sharing program, so that two users (peers) can send eachothers files in a secure way.
Currently I am able to do it in a non-secured version (meaning raw bytes are sent and received)

Thanks very much in advance,

Use a TLS connection. TLS can be used for any data stream, not only HTTPS.

Alternatively, if you can't use PKI, but you've solved key management somehow, then you can just encrypt the payloads yourself:

1 Like

As @kornel said, TLS is the way forward. You mentioned securing files, so an alternative to AES-GCM-SIV, if you can't have TLS, is the secretstream from libsodium, that makes splitting larger files into chunks relatively easy.

This is offered by both sodiumoxide and (shameless plug) Orion.

2 Likes

Do you need to have the files still in an encrypted state when they arrive and get stored at the other end?

Things like TLS ensure your data is encrypted "on the line" but deliver unencrypted data. So it's safe while traversing the net but not once it's written out on the receiving machine.

I see that TLS, the crate you recommend, uses TcpStream, but I started to implement my program as udp packets. Also I would like to use the least amount of libraries possible, so I am more looking into a homemade solution where I encrypt data myself (using aes 256 for example).

once its received there is no need for data to be encrypted, so I plan to have a decryption algorithm

I already implemented my own algo to split large files into smaller chunks. I am only looking at the encryption part :wink:

Keep in mind that the UDP packets can silently be dropped, reordered and duplicated on the wire. If you tries to reimplement just reliable byte stream transport on top of the UDP you'll get the another TCP at best but not recognized/optimized by the internet router boxes.

3 Likes

Is there any particular reason you want or must use UDP?

If you use UDP to transfer large files you will need to take care of: Lost packets, out of order packets, timeouts, retries, generally reconstructing your file from fragments , and so on. This is all done by TCP already so why reinvent the wheel and do a lot of work doing it yourself?

One of the first pieces of advice one gets from anyone concerned about such security is "Don't try and implement a crypto system yourself". It's complicated to get right and unless you know what you are doing and take great care easy to make mistakes and build something insecure. Better to use ready made solutions made by experts that has been extensively used, reviewed and battle tested.

Of course if all this is just a learning exercise then go ahead.

2 Likes

Interesting point, thank you

I have done it myself :wink: its not much work, you can check on my github the code is public.

No for this part I also believe this way, that's why I am looking for a library to handle the encryption part.

That is the easy part.

Typically "amateurs" make their mistakes and create a broken crypto system in all the rest of the system. Using insecure random salts, insecure key distribution, transmitting messages with the same key, and so on and so on.

This was famously demonstrated by the cracking of the German Enima in WWII. Made a lot easier when a German wireless operator resent a modified message using the same key.

Even in my very limited real work on crypto communications, many years ago, I found a flaw in a NATO standard crypto device we were supposed to be compatible with. They had failed to encrypt the zero padding bytes in blocks at the end of messages.

3 Likes

I have the same recommendation as @ZiCog. As long as it's just for learning-purposes, go nuts. I'd still consider taking a look at the documentation and implementation of the aforementioned, just to see what kind of threats exist and how they are mitigated with secretstream.

If you still just want the raw "encryption" part, then look into AEADs (authenticated encryption). The XChaCha20-Poly1305 AEAD is good (in addition to the suggested AES-GCM-SIV). Both libraries I linked earlier support XChaCha20-Poly1305 as well.

1 Like

I took a look at sodiumoxide::crypto::secretstream - Rust and have a little question before digging into it:

with XChaCha20-Poly1305 do we get the same length of bytes once data is encrypted?

I don't think that's possible with modern AEAD based crypto. Also it would leak the information.

I depends on what you mean by same length. Encryption is done with XChaCha20, which is a stream cipher. This means that the ciphertext is the same length as the original plaintext, since there is no padding. In reality, you won't get the exact same length for a stream. Each stream message is individually authenticated in secretstream, which means each message has additional data appended to the ciphertext. The length of this data is what is called ABYTES in secretstream (I don't know if sodiumoxide documents this, but I know Orion has it listed).

I don't think that's possible with modern AEAD based crypto. Also it would leak the information.

Leaking the original length of the plaintext happens with (X)ChaCha20-Poly1305. This usually isn't an issue, but if it is, I'd just add some amount of extra bytes to simulate some padding I want, and then split it off during decryption.

I can't help noticing that there is a lot of "unsafe" in that code.
This makes me nervous.

1 Like

I like to live dangerously :wink:

TLS can be used over UDP — see DTLS. There's also QUIC (HTTP/3) that uses TLS over UDP.

In Rust it's normal to depend on 3rd party libraries. Especially for security you need a trusted implementation.

2 Likes