/// <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(); crypto.KeySize = 256; //in bits crypto.Key = key; crypto.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) { Console.WriteLine("Error disposing AES streams" + e); } return(data); }
/// <summary> /// A loop to check for received packets /// </summary> private void ReceiveLoop() { if (this.TcpConnection.Connected) { while (this.TcpConnection.Available < 0x10) { Thread.Sleep(50); } byte[] buffer = new byte[0x10]; this.TcpConnection.GetStream().Read(buffer, 0, 0x10); PacketReader Reader = new PacketReader(buffer); Reader.ReadShort(); this.MapleVersion = Reader.ReadShort(); Reader.ReadMapleString(); this.SendCrypto = new MapleCrypto(Reader.ReadBytes(4), (short)this.MapleVersion); this.ReceiveCrypto = new MapleCrypto(Reader.ReadBytes(4), (short)this.MapleVersion); this.Ready = true; while (this.TcpConnection.Connected) { if (this.TcpConnection.Available >= 4) { byte[] buffer2 = new byte[4]; this.TcpConnection.GetStream().Read(buffer2, 0, 4); int packetLength = MapleCrypto.GetPacketLength(buffer2); while (this.TcpConnection.Available < packetLength) { Thread.Sleep(20); } byte[] buffer3 = new byte[packetLength]; this.TcpConnection.GetStream().Read(buffer3, 0, packetLength); this.ReceiveCrypto.Crypt(buffer3); MapleCustomEncryption.Decrypt(buffer3); Client.HandlePacket(buffer3); } Thread.Sleep(5); } this.Ready = false; } }