Need to encrypt bytes from TcpStream before copying to writer


I am writing a proxy TcpServer that should read bytes from client, encrypt them and forward the encrypted bytes to another server. I wonder what is the right way to do it in Rust: write a custom TcpStream, or a custom codec, or is there any available crates that I can check for reference?

Updated: the byte stream is not a short message but might be a long stream (ex: a continuous raw data stream from another hardware)


1 Like

Do you need to pass chunks of a certain size to the encryption algorithm, or can you stream chunks of any size?

@alice I plan to use AES or DES so the input should have a fixed size.

One approach is something like this.

Alternatively using codec from tokio-util: playground. It doesn't compile because the playground currently isn't using the newest version of Tokio, so it's missing stream_reader, but should work with Tokio v0.2.16 or newer.

This version will perform reads and writes concurrently, instead of alternating between them like the previous approach.

1 Like

@alice Thanks a lot, I will go with the codec version.

Btw, I have one small question related to the call copy_with_encrypt: is there any elegant way that I can get a progress notification from it, for example, I want to be notified when it already copied 1 MB, or x MB. Or I should add a static counter variable inside the decode function to manually count it? Thanks.

You can put the total number of sent bytes into a watch channel. Note that you might want to ensure that the count isn't updated until the bytes are actually written, and not just when they have been encrypted. In the first solution, that's rather easy, but with the codec you might need something like this.

1 Like

@alice I will need some time to fully understand the ProgressWrite but I think I got the broad idea. Thank you :slight_smile:

Sounds like streaming encryption might be of interest to you. Take a look at orion which recently added a pure-Rust implementation of libsodiums secretstream. It uses authenticated encryption, while supporting automatic re-keying and setting other flags in the encrypted stream.