Ejemplo n.º 1
0
 public AESManager(AESKeyIVPair pair)
 {
     mAESProvider         = new AesCryptoServiceProvider();
     mAESProvider.Padding = PaddingMode.ISO10126;
     mAESProvider.Key     = pair.Key;
     mAESProvider.IV      = pair.IV;
 }
Ejemplo n.º 2
0
        // 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);
        }