Example #1
0
        private void ProcessHandshake()
        {
            short packetSize = BitConverter.ToInt16(packetBuffer, 0);

            if (cursor < packetSize + HANDSHAKE_HEADER_SIZE || OnHandshake == null)
            {
                return;
            }

            byte[] buffer = new byte[packetSize];
            Buffer.BlockCopy(packetBuffer, HANDSHAKE_HEADER_SIZE, buffer, 0, packetSize);

            var packet = new PacketReader(buffer);
            var info   = new ServerInfo {
                Version    = packet.ReadShort(),
                Subversion = packet.ReadMapleString(),
                SIV        = packet.ReadBytes(4),
                RIV        = packet.ReadBytes(4),
                Locale     = packet.ReadByte()
            };

            clientCipher = new MapleCipher(info.Version, info.SIV, aesCipher);
            serverCipher = new MapleCipher(info.Version, info.RIV, aesCipher);
            Encrypted    = true; //start waiting for encrypted packets

            OnHandshake(this, info);
            cursor = 0; //reset stream
        }
Example #2
0
        protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List <object> output)
        {
            CMapleClient client = context.GetAttribute <CMapleClient>(CMapleClient.attributeKey).Get();

            if (client.DecoderState == -1)
            {
                //检测长度
                if (input.WriterIndex >= 4)
                {
                    int packetHeader = input.ReadInt();
                    client.DecoderState = MapleCipher.getPacketLength(packetHeader);//MapleAESOFB.getPacketLength(packetHeader);
                    int aaa = 0;
                    client.m_RecvIv.Transform();
                }
                else
                {
                    return;
                }
            }


            if (input.ReadableBytes >= client.DecoderState)
            {
                client.DecoderState = -1;
                //IntPtr DecoderState = context.GetAttribute<IntPtr>(MapleClient.DecoderState).Get();
                //获取数据长度,创建一个空数组
                byte[] DecodePakcet = new byte[input.ReadableBytes];

                //读取正常数据区域
                input.ReadBytes(DecodePakcet);
                //解密成功后返回数据
                output.Add(DecodePakcet);
            }
        }
Example #3
0
        internal void Start(ServerInfo info)
        {
            if (info != null)
            {
                byte[] siv = new byte[4];
                byte[] riv = new byte[4];
                var    rng = new Random(Interlocked.Increment(ref rngSeed));

                rng.NextBytes(siv);
                rng.NextBytes(riv);

                clientCipher = new MapleCipher(info.Version, siv, aesCipher);
                serverCipher = new MapleCipher(info.Version, riv, aesCipher);

                var p = new PacketWriter(14, 16);
                p.WriteShort(info.Version);
                p.WriteMapleString(info.Subversion);
                p.WriteBytes(riv);
                p.WriteBytes(siv);
                p.WriteByte(info.Locale);

                SendRawPacket(p.ToArray());
            }

            Receive();
        }
Example #4
0
        internal void Start(ServerInfo info)
        {
            if (info != null)
            {
                var siv = new byte[4];
                var riv = new byte[4];

                Random.NextBytes(siv);
                Random.NextBytes(riv);

                m_clientCipher = new MapleCipher(info.Version, siv, m_aesCipher, CipherType.Encrypt);
                m_serverCipher = new MapleCipher(info.Version, riv, m_aesCipher, CipherType.Decrypt);

                using (var p = new PacketWriter(14, 16))
                {
                    p.WriteShort(info.Version);
                    p.WriteMapleString(info.Subversion);
                    p.WriteBytes(riv);
                    p.WriteBytes(siv);
                    p.WriteByte(info.Locale);

                    SendRawPacket(p.ToArray());
                }
            }

            Receive();
        }
Example #5
0
        public void EncryptDecrypt_ToClient_Succeeds()
        {
            var version   = (ushort)55;
            var aesKey    = (ulong)0x52330F1BB4060813;
            var iv        = (uint)0;
            var encryptor = new MapleCipher(version, aesKey);

            encryptor.SetIv(iv);

            var packet = new PacketWriter();

            packet.WriteByte(1);
            packet.WriteShort(2);
            packet.WriteInt(4);
            packet.WriteLong(8);
            var originalPacket  = packet.ToArray();
            var encryptedPacket = encryptor.Encrypt(packet.ToArray().AsSpan(), true);

            var decryptor = new MapleCipher(version, aesKey);

            decryptor.SetIv(iv);
            var decryptedPacket = decryptor.Decrypt(encryptedPacket.ToArray().AsSpan());

            Assert.AreEqual(originalPacket.ByteArrayToString(), decryptedPacket.ByteArrayToString());
        }
Example #6
0
        public Decryptor(uint version, uint iv, uint blockIV)
        {
            Cipher = new(version, iv);
            List <ICrypter> cryptSeq = InitCryptSeq(version, blockIV);

            cryptSeq.Reverse();
            DecryptSeq = cryptSeq.ToArray();
        }
Example #7
0
        public MapleClient()
        {
            using (var rng = new RNGCryptoServiceProvider())
            {
                rng.GetNonZeroBytes(SendIv);
                rng.GetNonZeroBytes(RecvIv);
            }

            unchecked
            {
                //ushort value = 0xFFFF - ServerSettings.MapleVersion;
                SendCipher = new MapleCipher((short)(0xFFFF - ServerSettings.MapleVersion), SendIv,
                                             MapleCipher.CipherType.Encrypt);
                RecvCipher = new MapleCipher(ServerSettings.MapleVersion, RecvIv, MapleCipher.CipherType.Decrypt);
            }
        }
Example #8
0
        public void Init([NotNull] TcpClient client)
        {
            // Allow Client to close immediately
            client.LingerState = new LingerOption(true, 0);

            byte[] sivBytes = new byte[4];
            byte[] rivBytes = new byte[4];
            Rng.GetBytes(sivBytes);
            Rng.GetBytes(rivBytes);
            Siv = BitConverter.ToUInt32(sivBytes);
            Riv = BitConverter.ToUInt32(rivBytes);

            Client        = client;
            NetworkStream = client.GetStream();
            MapleStream   = new MapleStream();
            SendCipher    = MapleCipher.Encryptor(VERSION, Siv, BLOCK_IV);
            RecvCipher    = MapleCipher.Decryptor(VERSION, Riv, BLOCK_IV);
        }
Example #9
0
        internal void Start(ServerInfo info)
        {
            m_serverCipher = new MapleCipher(info.Version, info.Riv, m_aesCipher, CipherType.Decrypt);
            m_clientCipher = new MapleCipher(info.Version, info.Siv, m_aesCipher, CipherType.Encrypt);

            PacketWriter pw = new PacketWriter(15, 17);

            pw.WriteShort(info.Version);
            pw.WriteMapleString(info.Subversion);
            pw.WriteBytes(info.Riv);
            pw.WriteBytes(info.Siv);
            pw.WriteShort(info.Locale);

            SendRawPacket(pw.ToArray());

            Receive();

            Debug.WriteLine("Started local server (toClient)");
        }
Example #10
0
        public void GetPacketLength_ToServer_Succeeds()
        {
            var version        = (ushort)55;
            var aesKey         = (ulong)0x52330F1BB4060813;
            var iv             = (uint)0;
            var cryptoInstance = new MapleCipher(version, aesKey);

            cryptoInstance.SetIv(iv);

            var packet = new PacketWriter();

            packet.WriteByte(1);
            packet.WriteShort(2);
            packet.WriteInt(4);
            packet.WriteLong(8);
            var originalPacket  = packet.ToArray();
            var encryptedPacket = cryptoInstance.Encrypt(packet.ToArray().AsSpan(), false);
            var decryptedLength = MapleCipher.GetPacketLength(encryptedPacket);

            Assert.AreEqual(originalPacket.Length, decryptedLength);
        }
Example #11
0
        public void Disconnect()
        {
            if (m_connected)
            {
                m_connected = false;
                m_encrypted = false;
                m_cursor    = 0;

                m_socket.Shutdown(SocketShutdown.Both);
                m_socket.Disconnect(false);
                m_socket.Dispose();

                m_clientCipher = null;
                m_serverCipher = null;

                if (OnDisconnected != null)
                {
                    OnDisconnected(this, null);
                }
            }
        }
Example #12
0
        public void CheckHeaderToServer_Valid_Succeeds()
        {
            var version        = (ushort)55;
            var aesKey         = (ulong)0x52330F1BB4060813;
            var iv             = (uint)0;
            var cryptoInstance = new MapleCipher(version, aesKey);

            cryptoInstance.SetIv(iv);

            var packet = new PacketWriter();

            packet.WriteByte(1);
            packet.WriteShort(2);
            packet.WriteInt(4);
            packet.WriteLong(8);
            var encryptedPacket = cryptoInstance.Encrypt(packet.ToArray().AsSpan(), false);
            var checkCrypto     = new MapleCipher(version, aesKey);

            checkCrypto.SetIv(iv);
            Assert.IsTrue(checkCrypto.CheckHeaderToServer(encryptedPacket));
        }
Example #13
0
        public CMapleClient(short Version, byte[] Riv, byte[] Siv, IChannel channel)
        {
            var userkey = new byte[] //europe maplestory key
            {
                0x13, 0x00, 0x00, 0x00,
                0x08, 0x00, 0x00, 0x00,
                0x06, 0x00, 0x00, 0x00,
                0xB4, 0x00, 0x00, 0x00,
                0x1B, 0x00, 0x00, 0x00,
                0x0F, 0x00, 0x00, 0x00,
                0x33, 0x00, 0x00, 0x00,
                0x52, 0x00, 0x00, 0x00
            };
            var aes = new AesCipher(userkey);

            //设置加密与解密
            m_RecvIv     = new MapleCipher(Version, Riv, aes, CipherType.Decrypt);
            m_SendIv     = new MapleCipher(Version, Riv, aes, CipherType.Encrypt);
            m_Session    = channel;
            DecoderState = -1;
        }
Example #14
0
        private void ProcessPacket()
        {
            while (cursor > PACKET_HEADER_SIZE && Connected)
            {
                int packetSize = MapleCipher.GetPacketLength(packetBuffer);
                if (cursor < packetSize + PACKET_HEADER_SIZE || OnPacket == null)
                {
                    return;
                }

                byte[] buffer = new byte[packetSize];
                Buffer.BlockCopy(packetBuffer, PACKET_HEADER_SIZE, buffer, 0, packetSize);
                serverCipher.Transform(buffer);

                cursor -= packetSize + PACKET_HEADER_SIZE;
                if (cursor > 0)
                {
                    Buffer.BlockCopy(packetBuffer, packetSize + PACKET_HEADER_SIZE, packetBuffer, 0, cursor);
                }
                OnPacket(this, buffer);
            }
        }
Example #15
0
        public void Disconnect(bool finished = true)
        {
            if (!Connected)
            {
                return;
            }

            Encrypted = false;
            Connected = false;

            cursor = 0;
            socket.Shutdown(SocketShutdown.Both);
            socket.Disconnect(!finished);

            if (!finished)
            {
                return;
            }

            clientCipher = null;
            serverCipher = null;
            OnDisconnected?.Invoke(this, null);
        }
Example #16
0
        public void EncryptDecryptProvider_ToClient_Succeeds()
        {
            var version   = (ushort)55;
            var aesKey    = (ulong)0x52330F1BB4060813;
            var iv        = (uint)0;
            var encryptor = new MapleCipher(version, aesKey);

            encryptor.SetIv(iv);

            var packet = new PacketWriter();

            packet.WriteByte(1);
            packet.WriteShort(2);
            packet.WriteInt(4);
            packet.WriteLong(8);
            var originalPacket  = packet.ToArray();
            var encryptedPacket = encryptor.Encrypt(packet.ToArray().AsSpan(), true);


            var waiter = new ManualResetEventSlim();

            var provider = new MapleCipherProvider(version, aesKey, toClient: false);

            provider.SetVectors(0, 0);
            var buffer = encryptedPacket.ToArray().AsMemory();

            provider.PacketFinished += received =>
            {
                Assert.AreEqual(originalPacket.Length, received.Length, "Packet length should match");
                Assert.AreEqual(originalPacket.ByteArrayToString(), received.ByteArrayToString());
                waiter.Set();
            };
            provider.Decrypt(buffer.Span);

            waiter.Wait();
        }
Example #17
0
        private void ManipulateBuffer()
        {
            if (m_encrypted)
            {
                const int HeaderSize = 4;

                while (m_cursor > HeaderSize && m_connected) //header room + still connected
                {
                    int packetSize = MapleCipher.GetPacketLength(m_packetBuffer);

                    if (m_cursor < packetSize + HeaderSize) //header + packet room
                    {
                        break;
                    }

                    byte[] buffer = new byte[packetSize];
                    Buffer.BlockCopy(m_packetBuffer, HeaderSize, buffer, 0, packetSize); //copy packet
                    m_serverCipher.Transform(buffer);                                    //decrypt

                    m_cursor -= packetSize + HeaderSize;                                 //fix len

                    if (m_cursor > 0)                                                    //move reamining bytes
                    {
                        Buffer.BlockCopy(m_packetBuffer, packetSize + HeaderSize, m_packetBuffer, 0, m_cursor);
                    }

                    if (OnPacket != null)
                    {
                        OnPacket(this, buffer);
                    }

                    buffer = null; //get rid of buffer
                }
            }
            else if (m_cursor >= 2)
            {
                const int HeaderSize = 2;

                short packetSize = BitConverter.ToInt16(m_packetBuffer, 0);

                if (m_cursor >= packetSize + HeaderSize)
                {
                    byte[] buffer = new byte[packetSize];
                    Buffer.BlockCopy(m_packetBuffer, HeaderSize, buffer, 0, packetSize);

                    PacketReader packet = new PacketReader(buffer);

                    short  major = packet.ReadShort();
                    string minor = packet.ReadMapleString();

                    m_clientCipher = new MapleCipher(major, packet.ReadBytes(4), m_aesCipher, CipherType.Encrypt);
                    m_serverCipher = new MapleCipher(major, packet.ReadBytes(4), m_aesCipher, CipherType.Decrypt);

                    byte locale = packet.ReadByte();

                    m_encrypted = true; //start waiting for encrypted packets

                    if (OnHandshake != null)
                    {
                        var info = new ServerInfo()
                        {
                            Version    = major,
                            Subversion = minor,
                            Locale     = locale
                        };

                        OnHandshake(this, info);
                    }

                    buffer   = null; //get rid of buffer
                    m_cursor = 0;    //reset stream
                }
            }
        }
Example #18
0
        protected override int GetBodyLengthFromHeader(byte[] header, int offset, int length)
        {
            var result = MapleCipher.GetPacketLength(header.CloneRange(offset, length));

            return(result);
        }
Example #19
0
 public Encryptor(uint version, uint iv, uint blockIV)
 {
     Cipher     = new(version, iv);
     EncryptSeq = InitCryptSeq(version, blockIV).ToArray();
 }