问题描述
我正在一个项目中,我需要实现加密以通过tcp连接发送大量数据。我希望用C#编写。该项目也是我学习的一部分,通过实施这种加密,我将获得经验。
我已经进行了一些研究并测试了一些东西,并且写了我认为如何在下面实现它。
基本上,我想问是否有人可以检查我在下面写的内容,并警告我任何错误,安全漏洞或我所作的不正确陈述。指出这些问题并说明我应该采取的纠正措施。
- 我们通过TCP连接了主机A和B。
- 主机A通过
System.Security.Cryptography.RSA
创建RSA.Create(2048)
的实例。通过这样做,RSA实例创建了随机的公钥和私钥。私钥可用于解密由公钥加密的数据。公钥可以从私钥派生,但是不可能反向。 - A调用
rsa.ExportParameters(includePrivateParameters: false);
导出公共密钥,并使用诸如XmlSerializer
之类的序列化程序将RSAParameters
对象序列化为字节。然后,A可以通过TCP将序列化的对象发送给B,而无需进行加密。 - B接收
RSAParameters
对象并将其反序列化,并使用它来创建自己的RSA实例:RSA.Create(deserializedRSApar);
。 B的RSA对象现在具有A的RSA的公钥,因此可以加密数据,因此A只能由A拥有私钥来解密它。 - B在CBC模式下使用256位密钥和16字节IV创建一个
System.Security.Cryptography.Aes
实例。 - B使用带有导入的公共密钥的RSA对象加密AES密钥,并将其发送回A。
- A接收加密的数据并使用其私钥对其解密,并创建它自己的
System.Security.Cryptography.Aes
实例,并设置它解密的密钥。由于两个主机具有相同的AES密钥,因此现在可以处置RSA对象。 - 进一步的通信将在单独的消息中使用AES进行加密,主机需要为每个消息使用不同的不可预测的IV,IV将在加密数据之前以纯字节开头。我还将把给定消息的长度放在IV之后和加密数据之前。.我已经写了它,是在之前之前写了数据的长度,因为我听说AES没有加密时更改数据长度。
用于发送的方法的一部分应如下所示:
aes.GenerateIV();
using(var writer = new BinaryWriter(networkStream))
using(var encryptor = aes.CreateEncryptor())
using(var cryptoWriter = new CryptoStream(networkStream,encryptor,CryptoStreamMode.Write))
{
writer.Write(aes.IV);
writer.Write((int)bytesToSend.Length);
cryptoWriter.Write(bytesToSend,bytesToSend.Length);
}
接收方法的一部分应该看起来像这样:
using(var reader = new BinaryReader(networkStream))
using(var decryptor = aes.CreateDecryptor(aes.Key,reader.ReadBytes(aes.IV.Length)))
using(var cryptoReader = new CryptoStream(networkStream,decryptor,CryptoStreamMode.Read))
{
int toRead = reader.ReadInt32();
if (toRead > bufferArray.Length)
throw new Exception("Throw an exception or handle in another way,unimportant for Now");
cryptoReader.Read(bufferArray,toRead);
}
我知道我应该在方法范围之外创建那些BinaryReaders和Writers,我在这里写了uses(以及那些不必要的(int)强制转换),以显示出自己的意图,而不是“在类中有BinaryReader该方法的摘录位于“
我想问的另一个问题是:消息会持续多久有关系吗?消息的大小有限制吗?我不打算发送大于32kB的消息。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)