在同一 CryptoStream 上使用 BinaryReader 和 BinaryWriter 时如何避免超时?
How do I avoid timeout when using BinaryReader and BinaryWriter on the same CryptoStream?
我有一个程序使用 BinaryReader 和 BinaryWriter 发送 string, int 和 byte[] 网络上的消息。
消息的顺序和内容对于服务器和客户端的执行流程都很重要,但持续时间永远不会太长。
现在我正在尝试加密所有内容。
这是我对实际代码的新包装:
using encReaderStream = CryptoStream(clientStream, myAES.CreateDecryptor(), CryptoStreamMode.Read),\
encWriterStream = CryptoStream(clientStream, myAES.CreateEncryptor(), CryptoStreamMode.Write),\
enc_reader = BinaryReader(encReaderStream),\
enc_writer = BinaryWriter(encWriterStream):
....
此示例是 boo 代码,但直观上应该等同于此示例中的 C#。
现在发生的是服务器使用 enc_reader.ReadString()
正确获取第一条加密消息,并使用 enc_writer.Write("Accepted")
进行回复。但是客户永远得不到答案。
我已经测试了消息的顺序是否重要,确实如此。如果我改为从服务器发送一个字符串开始,那么客户端会收到它,但如果我继续发送消息,我很快就会遇到同样的情况。
我有一些想法,CryptoStream 可能与 BinaryReader/BinaryWriter 无法正确合作有关,但我不知道如何以好的方式解决这个问题。
我的服务器有很多函数只需要一个 BinaryReader 和一个 BinaryWriter,如果它们可以的话会非常方便像以前一样工作。
编辑:
我还在一个小型 C# 项目中复制了这种情况 here,使用上述的 AES 和 CTR 模式实现。
您不能刷新块中间的块密码,因为从算法的角度来看,这些字节还没有准备好。他们没有确定。
最好的解决方法可能是使用流密码。 .NET 对此的内置支持很差。拉入一个以计数器模式实现 AES 的库。
请注意,如果不使用经过身份验证的加密(并且看起来您不会这样做),攻击者可以编辑数据,尽管他们无法读取数据。使用 AES-GCM 来缓解。
后来我们发现您使用的CTR模式库坏了。使用这个:
public int InputBlockSize { get { return 1; } }
public int OutputBlockSize { get { return 1; } }
我有一个程序使用 BinaryReader 和 BinaryWriter 发送 string, int 和 byte[] 网络上的消息。
消息的顺序和内容对于服务器和客户端的执行流程都很重要,但持续时间永远不会太长。
现在我正在尝试加密所有内容。
这是我对实际代码的新包装:
using encReaderStream = CryptoStream(clientStream, myAES.CreateDecryptor(), CryptoStreamMode.Read),\
encWriterStream = CryptoStream(clientStream, myAES.CreateEncryptor(), CryptoStreamMode.Write),\
enc_reader = BinaryReader(encReaderStream),\
enc_writer = BinaryWriter(encWriterStream):
....
此示例是 boo 代码,但直观上应该等同于此示例中的 C#。
现在发生的是服务器使用 enc_reader.ReadString()
正确获取第一条加密消息,并使用 enc_writer.Write("Accepted")
进行回复。但是客户永远得不到答案。
我已经测试了消息的顺序是否重要,确实如此。如果我改为从服务器发送一个字符串开始,那么客户端会收到它,但如果我继续发送消息,我很快就会遇到同样的情况。
我有一些想法,CryptoStream 可能与 BinaryReader/BinaryWriter 无法正确合作有关,但我不知道如何以好的方式解决这个问题。
我的服务器有很多函数只需要一个 BinaryReader 和一个 BinaryWriter,如果它们可以的话会非常方便像以前一样工作。
编辑:
我还在一个小型 C# 项目中复制了这种情况 here,使用上述的 AES 和 CTR 模式实现。
您不能刷新块中间的块密码,因为从算法的角度来看,这些字节还没有准备好。他们没有确定。
最好的解决方法可能是使用流密码。 .NET 对此的内置支持很差。拉入一个以计数器模式实现 AES 的库。
请注意,如果不使用经过身份验证的加密(并且看起来您不会这样做),攻击者可以编辑数据,尽管他们无法读取数据。使用 AES-GCM 来缓解。
后来我们发现您使用的CTR模式库坏了。使用这个:
public int InputBlockSize { get { return 1; } }
public int OutputBlockSize { get { return 1; } }