2

그래서 TcpClient 및 TcpListener 클래스를 사용하여 간단한 "웹 채팅"을 만들고 있습니다. 보내진 모든 데이터를 암호화하여 암호화하고 AES 암호화를 사용하고 싶습니다. 먼저 서버의 AES 키가 안전하게 클라이언트에 전송되는지 확인해야합니다. RSA를 사용하여 AES 키를 암호화 한 다음이를 클라이언트에 보내면 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

문제는 발생하지 않습니다. 클라이언트에 대한 공개 키를 안전하게 보호하는 방법은 무엇입니까? 그렇지 않은 경우 클라이언트 코드에 공개 키를 포함시키고 개인 키를 서버 코드 (또는 구성)에 포함시키는 키 쌍을 생성하는 것이 좋습니다. –

답변

4

죄송합니다.

클라이언트에 공개 키를 보냈습니다. 이렇게하면 클라이언트가 서버로 전송할 데이터를 암호화 할 수 있습니다. 데이터를 해독하기 위해 클라이언트는 개인 키가 필요합니다 (따라서 사용자의 예외)

누군가에게 공개 키를 보내면 암호화 된 메시지를 보낼 수 없으므로 암호화 된 메시지를 안전하게 보낼 수 있습니다. 클라이언트는 암호화 된 메시지를 보낼 수 있습니다.

시나리오에서 이것은 클라이언트가 AES 키를 생성하고 전송 된 공개 키를 사용하여 암호화 한 다음 서버가 해독하여 AES 키를 사용할 수 있음을 의미합니다. 그러나 나는 중간 공격에있는 사람에게 매우 감염되기 쉬운 것을 포함하여 많은 결점을 가지고 있기 때문에 이것을 추천하지는 않을 것이다. 우리가받는 공개 키가 서버에 속하는지 확인하는 방법이 없기 때문입니다 (다른 사람이 자신의 키 쌍을 삽입하여 AES 키에 액세스 할 수 있도록 TCP 스트림을 가로 채고 수정할 수 있습니다. 통신의 나머지 부분을 스누핑 할 수 있음).

당신은 당신이 당신이 된 것처럼 다음 클라이언트가 키를 생성하자받은 공개 키를 확인하기 위해 몇 가지 메커니즘이 필요가에 전달하고 싶었 경우 SslStream 클래스 http://msdn.microsoft.com/en-us/library/system.net.security.sslstream(v=vs.100).aspx

을 사용으로 찾고 고려해야합니다.

일반적으로 공개 키를 확인하는 방법은 인증서를 사용하는 것입니다 (즉, 서버와 클라이언트가 모두 트러스트하고 타사가 실제로 공개 키에 속한다고 말하는 공개 키에 서명 한 제 3 자 (인증 기관)이 있음). 서버)

신뢰할 수있는 인증 기관에서 서명 한 인증서를 얻지 않으려면 자체 서명 된 인증서를 사용할 수 있지만 클라이언트 응용 프로그램에 공개 키를 하드 코딩하는 것 이상의 이점은 없습니다 어쨌든 자체 서명 된 인증서의 인증서 지문을 하드 코드해야합니다.

+0

이것은 숙제 일 뿐이므로 실제로 인증서를 사용하고 싶지 않습니다 ... 클라이언트에서 RSA를 만든 다음 서버에 공개 키를 보내고 AES 서버 키를 암호화하여 클라이언트에게 보낼 수 있다고 말하고 있습니다. 해독 할 수 있고 AES가 작동할까요? – n32303

+0

나는이 "내 방식"을 시도하고 작동 .. 대답 주셔서 감사합니다! – n32303

+0

당신은 할 수는 있지만 중간 공격을당하는 사람에게는 여전히 감염 될 수 있습니다. – DanL