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 }
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); } }
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(); }
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(); }
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()); }
public Decryptor(uint version, uint iv, uint blockIV) { Cipher = new(version, iv); List <ICrypter> cryptSeq = InitCryptSeq(version, blockIV); cryptSeq.Reverse(); DecryptSeq = cryptSeq.ToArray(); }
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); } }
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); }
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)"); }
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); }
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); } } }
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)); }
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; }
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); } }
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); }
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(); }
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 } } }
protected override int GetBodyLengthFromHeader(byte[] header, int offset, int length) { var result = MapleCipher.GetPacketLength(header.CloneRange(offset, length)); return(result); }
public Encryptor(uint version, uint iv, uint blockIV) { Cipher = new(version, iv); EncryptSeq = InitCryptSeq(version, blockIV).ToArray(); }