c# – 在不知道字节数的情况下读取特殊流
在你去使用
Jon Skeet’s answer之前,我不能.
我是 using this stream,一开始很棒,但现在,我遇到了一个小问题.我现在处于一个我不知道我期望的数据量的地方,所以我认为我会使用Jon Skeet提供的方法,但不幸的是,当所有数据包都被读取时,它会等待packet = mPackets.Take() . 我不知道如何解决这个问题,流做了它应该做的事情(在开始时),这是一个我不希望它做它为…做的事情的场合. 我是否应该尝试重写等待流,或者是否有一种不同的readall方法可以在我的情况下更好地工作? 我已经尝试在没有更多可用数据包时返回0(当我希望它读取所有数据而不是等待时)但是它会抛出流结束异常的IO结束. 我真的很茫然,我知道我为自己挖了一个深洞…… 到目前为止,我还没有能够提出一个更好的解决方案,而不是从总长度中减去TLS标题和GCM IV和MAC(如下所述)这对我现在使用的1套件工作正常,但不能很好地吹嘘用于未来的密码套件. 关于我为什么这样做的一些背景: 我正在使用mockPskTlsServer and client并且我已经创建了它: WaitingStream mStdin = new WaitingStream(); WaitingStream mStdout = new WaitingStream(); CryptoPskTlsClient mServer = new CryptoPskTlsClient(null); SecureRandom secureRandom = new SecureRandom(); TlsClientProtocol TlsProtocol = new TlsServerProtocol(Stdin,Stdout,secureRandom); TlsProtocol.Connect(mServer); 这样工作正常,我还在等待流中添加了一个事件,当流的输出时会触发该事件.这样我就可以在创建它时获得多个握手消息. 这一切都运行良好,本来可以做得更好(不那么……被黑了?)但它确实做了它应该做的事情. 我知道如何让它工作,但这是一个HACK,我正在寻找一种优雅的方式来做到这一点.以下是其中一个HACKS的代码示例: public override string DecryptData(string ciphertext) { byte[] ciphertextBuff = ASCIIEncoding.Default.GetBytes(ciphertext); mStdin.Write(ciphertextBuff,ciphertextBuff.Length); Stream tlsStream = mServerProtocol.Stream; byte[] plaintextBuffer = new byte[ciphertextBuff.Length - 29];//filthy HACK 29 bytes bij AES-GCM want TLS packet = 5,GCM IV = 8,GCM-MAC = 16 totaal = 29. Streams.ReadFully(tlsStream,plaintextBuffer); string plaintext = ASCIIEncoding.Default.GetString(plaintextBuffer); return plaintext; } 或者通过将x保留字节中的明文长度预先添加到TLS包中并在解密之前检索这些字节. 但正如您可以从代码示例中清楚地看到,read fully方法中的缓冲区必须是我想要提取的字节长度,它可能小于流所具有的但却不能更多,因为它会无限期地等待. 当我在谈论像ReadAll和ReadFully I mean these methods这样的方法时 解决方法
这肯定是你尝试这项工作的致命缺陷.您要做的是隐含在TCP连接上发送的数据是TLS加密的.它产生高度随机的字节值,0到255之间的任何值都是可能的.您从套接字的Read()调用中收到的数据包是byte [],而不是字符串. 将byte []转换为字符串需要使用.NET Encoding类.它有很多种,库存的是ASCIIEncoding,UnicodeEncoding,UTF8Encoding.还有一些用于处理特定代码页的自定义代码页,您可以使用Encoding(int codePage)构造函数来获取它们. 我们不知道您需要使用的“TCP层”使用什么编码,UTF8很可能,但是当它被要求用加密转换byte []时它总会产生损坏的数据.内容.某些字节值没有相应的Unicode代码点.编码对象通过生成一个?来解决那种问题.或者a作为替代品.无论Encoding.EncoderFallback的价值是多少.您可以在调试器中看到它们的一些可能性,尽管频率是不可预测的. 换句话说,加密数据将不可避免地被这些替换破坏.没有解决方法,因为内容因替换而丢失,所以无法恢复原始字节[].这必须由较低层解决,它们需要将byte []内容编码为始终可以转换的字符串(base64是标准解决方案),或者需要停止将数据转换为字符串.你确实需要raw byte []才能使这个工作. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |