2

Итак, я создаю простой «веб-чат», используя классы TcpClient и TcpListener. Я хочу, чтобы все данные были отправлены, и я использую шифрование AES. Поэтому сначала я должен убедиться, что ключ AES от сервера надежно отправлен клиенту. Я пытаюсь добиться этого, зашифровав ключ AES с помощью RSA, а затем отправив его клиенту и расшифровывая его с помощью RSA.Ключ не существует при попытке расшифровки с помощью RSA

Итак, прежде всего, я создал RSACryptoServiceProvider на сервере и извлек открытый ключ. Я отправил открытый ключ клиенту и создал RSACryptoServiceProvider и импортировал этот ключ. Когда я вызываю метод 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); 
+0

Ничего общего с вашей проблемой: как осуществляется передача открытого ключа клиенту? Если это не так, я предлагаю создать пару ключей, внедрить открытый ключ в код клиента и вставить закрытый ключ в код сервера (или config). –

ответ

4

К сожалению, это не был достаточно мал, чтобы поместиться в комментарии.

Вы отправили открытый ключ клиенту. Это позволит клиенту зашифровать данные для отправки на сервер. Для дешифрования данных клиенту понадобится закрытый ключ (отсюда и ваше исключение)

Отправка вашего открытого ключа кому-то не позволяет отправлять им зашифрованные сообщения, что позволяет им безопасно отправлять зашифрованные сообщения, поэтому в вашем примере клиент может отправить зашифрованное сообщение.

В вашем сценарии это означало бы, что клиенту необходимо создать ключ AES, зашифровать его, используя открытый ключ, который он был отправлен, а затем сервер может расшифровать его и использовать ключ AES. ОДНАКО Я бы не рекомендовал это, поскольку у него много недостатков, в том числе очень восприимчивый к человеку в средней атаке. Это связано с тем, что мы не можем проверить, что открытый ключ, который мы получаем, принадлежит тому, который принадлежит серверу (некоторые могут перехватывать и изменять поток tcp, чтобы вставлять свою собственную пару ключей и тем самым получать доступ к ключу AES и возможность отслеживать остальную часть сообщения).

Вы должны рассмотреть вопрос о поиске в использовании класса SslStream http://msdn.microsoft.com/en-us/library/system.net.security.sslstream(v=vs.100).aspx

Если вы хотите продолжать, как вы были тогда вы должны позволить клиенту генерировать ключ и иметь некоторый механизм проверки открытого ключа получил.

Обычно для проверки открытых ключей используется сертификаты (т. Е. У вас есть сторонняя организация (центр сертификации), которой доверяют сервер и клиент, и что третья сторона подписала открытый ключ, заявив, что она действительно принадлежит к сервер)

Если вы не хотите получать сертификат, подписанный доверенным центром сертификации, тогда вы можете использовать самоподписанный сертификат, но не так много выгоды от простого кодирования открытого ключа в клиентском приложении, поскольку вы в любом случае придется жестко печатать отпечаток сертификата самоподписанного сертификата.

+0

хорошо, это просто для домашних заданий, поэтому я действительно не хочу использовать сертификаты ... вы говорите, что я могу создать RSA на клиенте, затем отправить открытый ключ на сервер, а затем зашифровать ключ сервера AES и отправить его клиенту, который может расшифровать его, и AES будет работать? – n32303

+0

Я пробовал этот «мой путь», и он работает .. спасибо за ответ! – n32303

+0

Вы могли бы, но вы все равно будете восприимчивы к человеку в средней атаке. – DanL

Смежные вопросы