Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 尝试使用RSA解密时密钥不存在_C#_Cryptography_Rsa_Rsacryptoserviceprovider_Aescryptoserviceprovider - Fatal编程技术网

C# 尝试使用RSA解密时密钥不存在

C# 尝试使用RSA解密时密钥不存在,c#,cryptography,rsa,rsacryptoserviceprovider,aescryptoserviceprovider,C#,Cryptography,Rsa,Rsacryptoserviceprovider,Aescryptoserviceprovider,因此,我使用TcpClient和TcpListener类创建了一个简单的网络聊天。我希望发送的所有数据都被加密,我正在使用AES加密。所以首先我必须确保服务器的AES密钥被安全地发送到客户端。我正试图通过使用RSA加密AES密钥,然后将其发送到客户端,然后再次使用RSA解密来实现这一点 所以首先我在服务器上创建了一个RSACryptServiceProvider并提取了公钥。我将公钥发送到客户机,然后创建了一个CryptoServiceProvider并导入了该密钥。当我调用Decrpyt方法时

因此,我使用TcpClient和TcpListener类创建了一个简单的网络聊天。我希望发送的所有数据都被加密,我正在使用AES加密。所以首先我必须确保服务器的AES密钥被安全地发送到客户端。我正试图通过使用RSA加密AES密钥,然后将其发送到客户端,然后再次使用RSA解密来实现这一点

所以首先我在服务器上创建了一个RSACryptServiceProvider并提取了公钥。我将公钥发送到客户机,然后创建了一个CryptoServiceProvider并导入了该密钥。当我调用Decrpyt方法时,我得到一个键不存在异常。这是我的代码:

服务器:

这是向客户端发送公钥

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
string privateXml = rsa.ToXmlString(true);
string publicXml = rsa.ToXmlString(false);
Byte[] pubKey = Encoding.UTF8.GetBytes(publicXml);
clientStream.Write(pubKey, 0, pubKey.Length); 

AesCryptoServiceProvider aes = new AesCryptoServiceProvider(); // simetrično kriptiranje
byte[] aesKey = aes.Key;
byte[] encryptedRSA = rsa.Encrypt(aesKey, false);

clientStream.Write(encryptedRSA, 0, encryptedRSA.Length);
客户:

Byte[] serverPublicKey = new Byte[1024];

Int32 bytes1 = stream.Read(serverPublicKey, 0, serverPublicKey.Length); 
string serverKey = Encoding.UTF8.GetString(serverPublicKey, 0, bytes1);
serverKey = serverKey.Replace("\0", ""); 

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(serverKey);

Byte[] bytes2 = new Byte[128];
String aesKey = null;
stream.Read(bytes2, 0, bytes2.Length);

byte[] decryptedKey = rsa.Decrypt(bytes2, false);

很抱歉,这不够小,无法放入评论

您已将公钥发送到客户端。这只允许客户端加密要发送到服务器的数据。要解密数据,客户端需要一个私钥,因此会出现异常

向某人发送公钥不允许您向他们发送加密消息,而是允许他们安全地向您发送加密消息,因此在您的示例中,只有客户端可以发送加密消息

在您的场景中,这意味着客户端需要生成AES密钥,使用发送的公钥对其进行加密,然后服务器可以对其解密并使用AES密钥。然而,我不推荐这个,因为它有很多缺陷,包括对中间人攻击非常敏感。这是因为我们无法验证我们收到的公钥是否属于服务器。其他人可能正在拦截和修改tcp流,以插入他们自己的密钥对,从而获得AES密钥的访问权,并能够窥探通信的其余部分

你应该考虑使用SSLFISH类

如果您想继续这样做,那么您需要让客户机生成密钥,并有一些机制来验证收到的公钥

验证公钥的通常方法是使用证书,即您拥有服务器和客户端都信任的第三方证书颁发机构,并且该第三方已签署公钥,表示它确实属于服务器


如果您不想获得由受信任的证书颁发机构签名的证书,则可以使用自签名证书,但仅将公钥硬编码到客户端应用程序中没有多大好处,因为您必须硬编码自签名证书的证书指纹。

与此无关您的问题:向客户端发送公钥的安全性如何?如果不是,我建议生成一个密钥对,在客户端代码中嵌入公钥,在服务器代码或配置中嵌入私钥。。。你是说我可以在客户端创建RSA,然后将公钥发送到服务器,然后加密AES服务器密钥并将其发送到客户端,客户端可以对其进行解密,AES就可以工作了?我尝试了我的方法,它可以工作。。谢谢你的回答!!你可以,但你仍然容易受到中间人的攻击。