public AESManager(AESKeyIVPair pair) { mAESProvider = new AesCryptoServiceProvider(); mAESProvider.Padding = PaddingMode.ISO10126; mAESProvider.Key = pair.Key; mAESProvider.IV = pair.IV; }
// isServer : EventClient를 생성하는 프로세스가 서버인지를 나타냄. false일 경우 Ping을 먼저 보내지 않음. public EventClient(TcpClient client, bool isServer) { if (client == null) { throw new ArgumentNullException("client"); } mLowClient = client; mNetStream = client.GetStream(); ConnectedTime = DateTime.Now; mLastPingReceive = mLastPingSend = ConnectedTime; DoesSendPing = isServer; IP = ((IPEndPoint)client.Client.RemoteEndPoint).Address; Debug.Message($"EventClient의 생성자에서 프로퍼티를 할당하였음 : {ConnectedTime}, {IP}"); Debug.Message($"{IP}와 연결 준비 중..."); IsOnline = true; bool cryptoSuccess = false; string exceptionMessage = "타임 아웃"; Task.Run(() => { try { if (isServer) { // 1. 서버가 RSA 공개키를 클라이언트에 전송함. Debug.Message($"{IP}에 RSA 공개키 전송..."); mRSA = new RSAManager(); byte[] pubKey = Encoding.UTF8.GetBytes(mRSA.PublicKeyXML); Packet rsaPacket = new Packet(PacketType.RSAPublic, pubKey.Length); mNetStream.Write(rsaPacket.ToBytes(), 0, Packet.SIZE); mNetStream.Write(pubKey, 0, pubKey.Length); Debug.Message($"전송 완료."); // 4. 클라이언트가 보낸 암호화된 AES 비밀키(Key, IV)를 수신하고 AES 개체를 초기화함. Debug.Message($"{IP}로 부터 AES 정보 수신..."); Packet aesPacket = ReceivePacket(PacketType.AESKey); byte[] enAESKey = ReceiveCompletely(aesPacket.DataLength); aesPacket = ReceivePacket(PacketType.AESIV); byte[] enAESIV = ReceiveCompletely(aesPacket.DataLength); AESKeyIVPair pair = new AESKeyIVPair(mRSA.Decrypt(enAESKey), mRSA.Decrypt(enAESIV)); mAES = new AESManager(pair); Debug.Message($"수신 완료."); } else { // 2. 서버가 보낸 RSA 공개키를 수신함. Debug.Message($"{IP}로 부터 RSA 공개키 수신..."); Packet rsaPacket = ReceivePacket(PacketType.RSAPublic); byte[] pubKey = ReceiveCompletely(rsaPacket.DataLength); string pubKeyXML = Encoding.UTF8.GetString(pubKey); Debug.Message($"수신 완료."); // 3. 수신한 공개키를 이용해 AES 비밀키(Key, IV)를 암호화하여 서버에 전송함. Debug.Message($"{IP}에 AES 정보 전송..."); mAES = new AESManager(); AESKeyIVPair pair = mAES.KeyIVPair; byte[] enKey = RSAManager.Encrypt(pair.Key, pubKeyXML); byte[] enIV = RSAManager.Encrypt(pair.IV, pubKeyXML); Packet aesKeyPacket = new Packet(PacketType.AESKey, enKey.Length); Packet aesIVPacket = new Packet(PacketType.AESIV, enIV.Length); mNetStream.Write(aesKeyPacket.ToBytes(), 0, Packet.SIZE); mNetStream.Write(enKey, 0, enKey.Length); mNetStream.Write(aesIVPacket.ToBytes(), 0, Packet.SIZE); mNetStream.Write(enIV, 0, enIV.Length); Debug.Message($"전송 완료."); } cryptoSuccess = true; } catch (Exception e) { exceptionMessage = e.Message; cryptoSuccess = false; } }).Wait(1000 * 60); if (!cryptoSuccess) { Debug.Error($"상대와 연결하는데 실패하였습니다 : {exceptionMessage}"); this.Disconnect(); return; } //Debug.Message($"AES Key/IV = {mAES.KeyIVPair.ToString()}"); ThreadPool.QueueUserWorkItem(ThreadLoop); }