Hello, im developing 4.8 aion on C#. I have done login server and communication between login & game server, now im trying to send&receive game packets (for now im trying to enter choosed server from server list).
when i got connection from user i send SM_KEY()
my crypt class
EncryptionKeyPair
my send packet
and receive
and i get error on
if (data[6] == (0xFF - data[3]))
when i got connection from user i send SM_KEY()
Code:
write(client.enableCryptKey());
my crypt class
Code:
public static byte staticServerPacketCode = 0x44;
private bool isEnabled;
private EncryptionKeyPair packetKey = null;
private static System.Random rnd = new System.Random();
public int enableKey()
{
if (packetKey != null)
return 0;
int key = rnd.Next();
packetKey = new EncryptionKeyPair(key);
//false key that will be sent to aion client in SM_KEY packet
return (int)((key ^ 0xCD92E4DF) + 0x3FF2CCCF);
}
public bool decrypt(ref byte[] data, int offset, int len)
{
try
{
if (!isEnabled)
{
return true;
}
return packetKey.decrypt(ref data, offset, len);
}
catch (Exception e)
{
Log.error("Decryption error " + e.Message);
Log.log(e.ToString());
}
return false;
}
public void encrypt(ref byte[] data, int offset, int len)
{
if (!isEnabled)
{
Console.WriteLine(isEnabled);
isEnabled = true;
return;
}
try
{
packetKey.encrypt(ref data, offset, len);
}
catch (Exception e)
{
Log.error("Encryption error " + e.Message);
Log.log(e.ToString());
}
}
public static byte encodeOpcode(int op)
{
return (byte)((op + 0xCF) ^ 0xDF);
}
EncryptionKeyPair
Code:
static int SERVER = 0;
static int CLIENT = 1;
static byte[] staticKey = Encoding.UTF8.GetBytes("nKO/WctQ0AVLbpzfBkS6NevDYT8ourG5CRlmdjyJ72aswx4EPq1UgZhFMXH?3iI9");
private static byte staticClientPacketCode = 0x65;
private int baseKey = 0;
private byte[][] keys = null;
public EncryptionKeyPair(int baseKey)
{
this.baseKey = baseKey;
keys = new byte[2][];
keys[SERVER] = new byte[] {
(byte) (baseKey & 0xff),
(byte) ((baseKey >> 8) & 0xff),
(byte) ((baseKey >> 16) & 0xff),
(byte) ((baseKey >> 24) & 0xff),
(byte) 0xa1,
(byte) 0x6c,
(byte) 0x54,
(byte) 0x87
};
keys[CLIENT] = new byte[keys[SERVER].Length];
Array.Copy(keys[SERVER], 0, keys[CLIENT], 0, keys[SERVER].Length);
}
public int getBaseKey()
{
return baseKey;
}
private bool validateClientPacket(byte[] data)
{
short zero = data[0], three = data[3];
byte two = data[2];
return zero == ~three && two == staticClientPacketCode;
}
public bool decrypt(ref byte[] data, int arrayIndex, int size)
{
byte[] clientPacketKey = keys[CLIENT];
int prev = data[arrayIndex];
data[arrayIndex++] ^= (byte)(clientPacketKey[0] & 0xff);
for (int i = 1; i < size; i++, arrayIndex++)
{
int curr = data[arrayIndex] & 0xff;
data[arrayIndex] ^= (byte)((staticKey[i & 63] & 0xff) ^ (clientPacketKey[i & 7] & 0xff) ^ prev);
prev = curr;
}
long oldKey = (((long)clientPacketKey[0] & 0xff) << 0) | (((long)clientPacketKey[1] & 0xff) << 8)
| (((long)clientPacketKey[2] & 0xff) << 16) | (((long)clientPacketKey[3] & 0xff) << 24)
| (((long)clientPacketKey[4] & 0xff) << 32) | (((long)clientPacketKey[5] & 0xff) << 40)
| (((long)clientPacketKey[6] & 0xff) << 48) | (((long)clientPacketKey[7] & 0xff) << 56);
oldKey += size;
if (data[6] == (0xFF - data[3]))
{
clientPacketKey[0] = (byte)(oldKey >> 0 & 0xff);
clientPacketKey[1] = (byte)(oldKey >> 8 & 0xff);
clientPacketKey[2] = (byte)(oldKey >> 16 & 0xff);
clientPacketKey[3] = (byte)(oldKey >> 24 & 0xff);
clientPacketKey[4] = (byte)(oldKey >> 32 & 0xff);
clientPacketKey[5] = (byte)(oldKey >> 40 & 0xff);
clientPacketKey[6] = (byte)(oldKey >> 48 & 0xff);
clientPacketKey[7] = (byte)(oldKey >> 56 & 0xff);
}
else
{
Log.error("Cryptographically incorrect packet received !");
Log.debug("Data: " + Utils.hexToString(data));
return false;
}
return true;
}
public void encrypt(ref byte[] data, int arrayIndex, int size)
{
byte[] serverPacketKey = keys[SERVER];
data[arrayIndex] ^= (byte)(serverPacketKey[0] & 0xff);
int prev = data[arrayIndex++];
for (int i = 1; i < size; i++, arrayIndex++)
{
data[arrayIndex] ^= (byte)((staticKey[i & 63] & 0xff) ^ (serverPacketKey[i & 7] & 0xff) ^ prev);
prev = data[arrayIndex];
}
long oldKey = (((long)serverPacketKey[0] & 0xff) << 0) | (((long)serverPacketKey[1] & 0xff) << 8)
| (((long)serverPacketKey[2] & 0xff) << 16) | (((long)serverPacketKey[3] & 0xff) << 24)
| (((long)serverPacketKey[4] & 0xff) << 32) | (((long)serverPacketKey[5] & 0xff) << 40)
| (((long)serverPacketKey[6] & 0xff) << 48) | (((long)serverPacketKey[7] & 0xff) << 56);
oldKey += size;
serverPacketKey[0] = (byte)(oldKey >> 0 & 0xff);
serverPacketKey[1] = (byte)(oldKey >> 8 & 0xff);
serverPacketKey[2] = (byte)(oldKey >> 16 & 0xff);
serverPacketKey[3] = (byte)(oldKey >> 24 & 0xff);
serverPacketKey[4] = (byte)(oldKey >> 32 & 0xff);
serverPacketKey[5] = (byte)(oldKey >> 40 & 0xff);
serverPacketKey[6] = (byte)(oldKey >> 48 & 0xff);
serverPacketKey[7] = (byte)(oldKey >> 56 & 0xff);
}
my send packet
Code:
packet.set(this);
packet.Position = 0;
if (!Packets.Game.server.ContainsKey(packet.GetType()))
{
Log.error($"Undefined packet to send to AION client [{packet.GetType()}]");
return;
}
byte opcode = Packets.Game.server[packet.GetType()];
byte cryptedOpcode = CryptEngine.encodeOpcode(opcode);
packet.write((short)0); // future length
packet.write(cryptedOpcode);
packet.write((byte)1);
packet.write(CryptEngine.staticServerPacketCode);
packet.write((short)(~cryptedOpcode)); // for checksum?
packet.write((byte)(0xFF - (byte)1));
packet.implement();
int len = (int)packet.Position;
byte[] result = new byte[len]; //slice
Array.Copy(packet.ToArray(), 0, result, 0, len);
crypt.encrypt(ref result, 2, len - 2);
packet.Position = 0; //flip
packet.write((short)len);
packet.write(result, 2, len - 2);
channel.SendAsync(packet.ToArray(), SocketFlags.None);
and receive
Code:
ushort size =
BitConverter.ToUInt16(
new byte[] { (byte)receiveStream.ReadByte(), (byte)receiveStream.ReadByte() }, 0);
receiveStream.Position -= 2;
while (size > 0 && size <= receiveStream.Length - receiveStream.Position)
{
byte[] data = new byte[size];
receiveStream.Read(data, 0, size);
if (crypt != null && !crypt.decrypt(ref data, 2, size - 2))
{
close();
return;
}
//Process packet
using MemoryStream stream = new MemoryStream(data, 2, data.Length - 2, false);
byte op = (byte)stream.ReadByte();
if (!Packets.Game.client.ContainsValue(op))
{
Log.warn("Undefined packet from AION client " + op);
//close(new SM_LOGIN_FAIL(ResponseType.SYSTEM_ERROR));
return;
}
stream.Position += 4;
ClientPacket<WConnection> main = Activator.CreateInstance(Packets.Game.client.FirstOrDefault(x => x.Value == op).Key) as ClientPacket<WConnection>;
byte[] maintain = new byte[stream.Length - stream.Position];
Array.Copy(stream.ToArray(), (int)stream.Position, maintain, 0, (int)(stream.Length - stream.Position));
main.set(this, maintain, 0);
main.execute();
if (receiveStream.Length - receiveStream.Position > 2)
{
size = BitConverter.ToUInt16(new byte[] { (byte)receiveStream.ReadByte(), (byte)receiveStream.ReadByte() }, 0);
receiveStream.Position -= 2;
}
else
size = 0;
}
int remain = (int)(receiveStream.Length - receiveStream.Position);
if (remain > 0)
{
byte[] remdata = new byte[remain];
receiveStream.Read(remdata, 0, remain);
receiveStream.Position = 0;
receiveStream.Write(remdata, 0, remdata.Length);
}
else
receiveStream.Position = 0;
and i get error on
if (data[6] == (0xFF - data[3]))