简体   繁体   中英

How do I avoid timeout when using BinaryReader and BinaryWriter on the same CryptoStream?

I have a program that uses BinaryReader and BinaryWriter to send string , int and byte [] messages over the network.

The order and content of the messages is significant for the flow of the execution on both server and client, but the duration is never long.

Now I'm trying to encrypt everything.

This is the new wrapper that I have around the actual code:

using encReaderStream = CryptoStream(clientStream, myAES.CreateDecryptor(), CryptoStreamMode.Read),\
      encWriterStream = CryptoStream(clientStream, myAES.CreateEncryptor(), CryptoStreamMode.Write),\
      enc_reader = BinaryReader(encReaderStream),\
      enc_writer = BinaryWriter(encWriterStream):
          ....

This example is boo code, but it should be intuitively equivalent to C# in this instance.

What happens now is that the server gets the first encrypted message correctly with enc_reader.ReadString() , and answers with enc_writer.Write("Accepted") . But the client never gets the answer.

I have tested if the order of the messages is significant, and it is. If I instead start by sending a string from the server, then the client gets it, but if I continue to send messages, I will soon get into the same situation.

I have some idea that CryptoStream might be responsible for not cooperating properly with BinaryReader / BinaryWriter , but I don't know how to sort out this mess in a good way.

My server has a lot of functions that just expects a BinaryReader and a BinaryWriter , and it would be super convenient if they could work like before.

EDIT:

I've also replicated the situation in a small C# project here , using the the mentioned implementation of AES with CTR mode.

You can't flush a block cipher in the middle of a block because those bytes are not ready from an algorithmic standpoint. They are not determined.

Probably, the best fix is to use a stream cipher. .NET has poor built-in support for that. Pull in a library that implements AES in counter mode.

Be aware that without using authenticated encryption (and it does not look like you are going it) attackers can edit the data although they cannot read it. Use AES-GCM to mitigate.


Later we found out that the CTR mode library you are using is broken. Use this:

public int InputBlockSize { get { return 1; } }
public int OutputBlockSize { get { return 1; } }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM