/// <summary>
        /// Encrypt data using MapleStory's AES method
        /// </summary>
        /// <param name="IV">IV to use for encryption</param>
        /// <param name="data">data to encrypt</param>
        /// <param name="length">length of data</param>
        /// <param name="key">the AES key to use</param>
        /// <returns>Crypted data</returns>
        public static byte[] AESCrypt(byte[] IV, byte[] data, int length, byte[] key)
        {
            AesManaged crypto = new AesManaged {
                KeySize = 256,           //in bits
                Key     = key,
                Mode    = CipherMode.ECB // Should be OFB, but this works too
            };

            MemoryStream memStream    = new MemoryStream();
            CryptoStream cryptoStream = new CryptoStream(memStream, crypto.CreateEncryptor(), CryptoStreamMode.Write);

            int remaining = length;
            int llength   = 0x5B0;
            int start     = 0;

            while (remaining > 0)
            {
                byte[] myIV = MapleCrypto.multiplyBytes(IV, 4, 4);
                if (remaining < llength)
                {
                    llength = remaining;
                }
                for (int x = start; x < (start + llength); x++)
                {
                    if ((x - start) % myIV.Length == 0)
                    {
                        cryptoStream.Write(myIV, 0, myIV.Length);
                        byte[] newIV = memStream.ToArray();
                        Array.Copy(newIV, myIV, myIV.Length);
                        memStream.Position = 0;
                    }
                    data[x] ^= myIV[(x - start) % myIV.Length];
                }
                start     += llength;
                remaining -= llength;
                llength    = 0x5B4;
            }

            try
            {
                cryptoStream.Dispose();
                memStream.Dispose();
            }
            catch (Exception e)
            {
                Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "Error disposing AES streams" + e);
                //Console.WriteLine("Error disposing AES streams" + e);
            }

            return(data);
        }
Exemple #2
0
        /// <summary>
        /// Encrypt data using MapleStory's AES method
        /// </summary>
        /// <param name="iv">IV to use for encryption</param>
        /// <param name="data">data to encrypt</param>
        /// <param name="length">length of data</param>
        /// <param name="key">the AES key to use</param>
        /// <returns>Crypted data</returns>
        public static byte[] AesCrypt(byte[] iv, byte[] data, int length, byte[] key)
        {
            var crypto = new AesManaged
            {
                KeySize = 256,
                Key     = key,
                Mode    = CipherMode.ECB // Should be OFB, but this works too
            };

            using (var memStream = new MemoryStream())
            {
                using (var cryptoStream = new CryptoStream(memStream, crypto.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    var remaining = length;
                    var size      = 0x5B0;
                    var start     = 0;

                    while (remaining > 0)
                    {
                        var myIv = MapleCrypto.MultiplyBytes(iv, 4, 4);
                        if (remaining < size)
                        {
                            size = remaining;
                        }

                        for (var x = start; x < start + size; x++)
                        {
                            if ((x - start) % myIv.Length == 0)
                            {
                                cryptoStream.Write(myIv, 0, myIv.Length);
                                var newIv = memStream.ToArray();
                                Array.Copy(newIv, myIv, myIv.Length);
                                memStream.Position = 0;
                            }

                            data[x] ^= myIv[(x - start) % myIv.Length];
                        }

                        start     += size;
                        remaining -= size;
                        size       = 0x5B4;
                    }
                }
            }

            return(data);
        }
Exemple #3
0
        /// <summary>
        /// Encrypt data using MapleStory's AES method
        /// </summary>
        /// <param name="pIV">IV to use for encryption</param>
        /// <param name="pData">data to encrypt</param>
        /// <param name="pLength">length of data</param>
        /// <param name="pKey">the AES key to use</param>
        /// <returns>Crypted data</returns>
        public static byte[] aesCrypt(byte[] pIV, byte[] pData, int pLength, byte[] pKey)
        {
            AesManaged crypto = new AesManaged {
                KeySize = 256, Key = pKey, Mode = CipherMode.ECB
            };

            MemoryStream memStream    = new MemoryStream();
            CryptoStream cryptoStream = new CryptoStream(memStream, crypto.CreateEncryptor(), CryptoStreamMode.Write);

            int remaining = pLength;
            int llength   = 0x5B0;
            int start     = 0;

            while (remaining > 0)
            {
                byte[] myIV = MapleCrypto.multiplyBytes(pIV, 4, 4);
                if (remaining < llength)
                {
                    llength = remaining;
                }
                for (int x = start; x < (start + llength); x++)
                {
                    if ((x - start) % myIV.Length == 0)
                    {
                        cryptoStream.Write(myIV, 0, myIV.Length);
                        byte[] newIV = memStream.ToArray();
                        Array.Copy(newIV, myIV, myIV.Length);
                        memStream.Position = 0;
                    }
                    pData[x] ^= myIV[(x - start) % myIV.Length];
                }
                start     += llength;
                remaining -= llength;
                llength    = 0x5B4;
            }

            try {
                cryptoStream.Dispose();
                memStream.Dispose();
            } catch (Exception e) {
                Console.WriteLine("Error disposing AES streams" + e);
            }

            return(pData);
        }
Exemple #4
0
        /// <summary>
        /// Encrypt data using MapleStory's AES method
        /// </summary>
        /// <param name="IV">IV to use for encryption</param>
        /// <param name="data">data to encrypt</param>
        /// <param name="length">length of data</param>
        /// <param name="key">the AES key to use</param>
        /// <returns>Crypted data</returns>
        public static byte[] AesCrypt(byte[] IV, byte[] data, int length, byte[] key)
        {
            AesManaged crypto = new AesManaged
            {
                KeySize = 256,           //in bits
                Key     = key,
                Mode    = CipherMode.ECB // Should be OFB, but this works too
            };

            using (MemoryStream memStream = new MemoryStream())
            {
                using (CryptoStream cryptoStream = new CryptoStream(memStream, crypto.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    int remaining = length;
                    int llength   = 0x5B0;
                    int start     = 0;
                    while (remaining > 0)
                    {
                        byte[] myIV = MapleCrypto.MultiplyBytes(IV, 4, 4);
                        if (remaining < llength)
                        {
                            llength = remaining;
                        }
                        for (int x = start; x < (start + llength); x++)
                        {
                            if ((x - start) % myIV.Length == 0)
                            {
                                cryptoStream.Write(myIV, 0, myIV.Length);
                                byte[] newIV = memStream.ToArray();
                                Array.Copy(newIV, myIV, myIV.Length);
                                memStream.Position = 0;
                            }
                            data[x] ^= myIV[(x - start) % myIV.Length];
                        }
                        start     += llength;
                        remaining -= llength;
                        llength    = 0x5B4;
                    }
                }
            }
            return(data);
        }
        /// <summary>
        /// Data received event handler
        /// </summary>
        /// <param name="iar">IAsyncResult of the data received event</param>
        private void OnDataReceived(IAsyncResult iar)
        {
            SocketInfo socketInfo = (SocketInfo)iar.AsyncState;
            try
            {
                int received = socketInfo.Socket.EndReceive(iar);
                if (received == 0)
                {
                    if (OnClientDisconnected != null)
                    {
                        OnClientDisconnected(this);
                    }
                    return;
                }

                socketInfo.Index += received;

                if (socketInfo.Index == socketInfo.DataBuffer.Length)
                {
                    switch (socketInfo.State)
                    {
                        case SocketInfo.StateEnum.Header:
                            if (socketInfo.NoEncryption)
                            {
                                PacketReader headerReader = new PacketReader(socketInfo.DataBuffer);
                                short packetHeader = headerReader.ReadShort();
                                socketInfo.State = SocketInfo.StateEnum.Content;
                                socketInfo.DataBuffer = new byte[packetHeader];
                                socketInfo.Index = 0;
                                WaitForData(socketInfo);
                            }
                            else
                            {
                                PacketReader headerReader = new PacketReader(socketInfo.DataBuffer);
                                byte[] packetHeaderB = headerReader.ToArray();
                                int packetHeader = headerReader.ReadInt();
                                short packetLength = (short)MapleCrypto.getPacketLength(packetHeader);
                                if (_type == SessionType.SERVER_TO_CLIENT && !_RIV.checkPacketToServer(BitConverter.GetBytes(packetHeader)))
                                {
                                    Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Packet check failed. Disconnecting client.");
                                    //this.Socket.Close();
                                }
                                socketInfo.State = SocketInfo.StateEnum.Content;
                                socketInfo.DataBuffer = new byte[packetLength];
                                socketInfo.Index = 0;
                                WaitForData(socketInfo);
                            }
                            break;
                        case SocketInfo.StateEnum.Content:
                            byte[] data = socketInfo.DataBuffer;
                            if (socketInfo.NoEncryption)
                            {
                                socketInfo.NoEncryption = false;
                                PacketReader reader = new PacketReader(data);
                                short version = reader.ReadShort();
                                string unknown = reader.ReadMapleString();
                                _SIV = new MapleCrypto(reader.ReadBytes(4), version);
                                _RIV = new MapleCrypto(reader.ReadBytes(4), version);
                                byte serverType = reader.ReadByte();
                                if (_type == SessionType.CLIENT_TO_SERVER)
                                {
                                    OnInitPacketReceived(version, serverType);
                                }
                                OnPacketReceived(new PacketReader(data), true);
                                WaitForData();
                            }
                            else
                            {
                                _RIV.crypt(data);
                                MapleCustomEncryption.Decrypt(data);
                                if (data.Length != 0 && OnPacketReceived != null)
                                {
                                    OnPacketReceived(new PacketReader(data), false);
                                }
                                WaitForData();
                            }
                            break;
                    }
                }
                else
                {
                    Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Warning] Not enough data");
                    WaitForData(socketInfo);
                }
            }
            catch (ObjectDisposedException)
            {
                Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Session.OnDataReceived: Socket has been closed");
            }
            catch (SocketException se)
            {
                if (se.ErrorCode != 10054)
                {
                    Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Session.OnDataReceived: " + se);
                }
            }
            catch (Exception e)
            {
                Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Session.OnDataReceived: " + e);
            }
        }