gpt4 book ai didi

c# - CryptoStream 没有像预期的那样刷新

转载 作者:太空狗 更新时间:2023-10-30 01:05:48 24 4
gpt4 key购买 nike

我正在处理的 C# .NET Framework 4.5 代码应该允许我通过加密流将文本传输到另一个程序。我创建了两个简单的程序来演示我的问题。 EncryptionTestA 是服务器,意味着首先运行。 EncryptionTestB 是客户端,旨在第二个运行。 EncryptionTestB 连接后,它通过 CryptoStream 将文本“hello world”传输到另一个程序。至少在理论上是这样。

实际发生的是什么。我通过在内部接口(interface)上使用 Wireshark 观察数据传输来确认这一点。此代码绝对不会以其当前形式传输任何数据。我能够让它发送“hello world”的唯一方法是关闭客户端的 StreamWriter。这样做的问题是它还会关闭底层的 TCP 连接,这是我不想做的。

那么,我的问题是:如何在不关闭底层 TCP 连接的情况下刷新 StreamWriter/CryptoStream?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Collections;
using System.Threading;
using System.Security;
using System.Security.Cryptography;
using System.Net;
using System.Net.Sockets;

namespace EncryptionTestA
{
class Program
{
static void Main(string[] args)
{
TcpListener listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 1892);
listener.Start();
TcpClient client = listener.AcceptTcpClient();
NetworkStream ns = client.GetStream();

Rijndael aes = RijndaelManaged.Create();
byte[] key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
byte[] iv = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
CryptoStream cs = new CryptoStream(ns, aes.CreateDecryptor(key, iv), CryptoStreamMode.Read);

StreamReader sr = new StreamReader(cs);

String test = sr.ReadLine();

Console.Read();

sr.Close();
cs.Close();
ns.Close();
client.Close();
listener.Stop();
}
}
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Collections;
using System.Threading;
using System.Security;
using System.Security.Cryptography;
using System.Net;
using System.Net.Sockets;

namespace EncryptionTestB
{
class Program
{
static void Main(string[] args)
{
TcpClient client = new TcpClient();
client.Connect(IPAddress.Parse("127.0.0.1"), 1892);
NetworkStream ns = client.GetStream();

Rijndael aes = RijndaelManaged.Create();
byte[] key = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
byte[] iv = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
CryptoStream cs = new CryptoStream(ns, aes.CreateEncryptor(key, iv), CryptoStreamMode.Write);

StreamWriter sw = new StreamWriter(cs);

sw.WriteLine("hello world");
sw.Flush();
//sw.Close();

Console.Read();

sw.Close();
cs.Close();
ns.Close();
client.Close();
}
}
}

最佳答案

我认为问题在于您使用的是 block 密码 - 它总是以 block 为单位工作,所以直到您到达关闭流的最后一个 block (此时您有一个带有一些描述的填充的较短 block )当你有一个部分块时,什么都不能写入流。

我强烈怀疑,如果您尝试加密比“hello world”更长的内容 - 尝试至少 16 个字符,甚至更多 - 您会发现在关闭之前得到一些 block 流,但除非您碰巧碰到数据末尾的 block 边界,否则您仍然会在末尾丢失一些数据。

目前尚不清楚您的最终用例是什么:如果您尝试在同一流上发送具有某种描述的多条消息,我鼓励您制定一个方案,分别加密每条消息,然后将所有通信 channel 上的数据 - 带有长度前缀,以便您知道接收方的加密消息有多大。

请注意,在接收端,我强烈建议您避免使用DataAvailable。仅仅因为流中现在没有可用数据并不意味着您已经到达消息的末尾...这就是您需要长度前缀的原因。

关于c# - CryptoStream 没有像预期的那样刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17266902/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com