Цитата:
Сообщение от supernewbie
Linux, шифрование начинается с пакета RequestServerList
|
А конкретнее: какой алгоритм, какие параметры?
В этих двух статьях я не нашел ссылки, что пакет RequestServerList как-то по особому должен шифроваться
Какие из приведенных ниже методов из этих статей надо применить к пакету?
Вспомогательные методы - Шифрация пакетов GameServer (KyberPrizrak)
Оффтоп
Код:
char key_sc[8];
char key_cs[8];
void Encrypt(char *raw, int size) {
int temp = 0;
for (int i=0; i<size; i++) {
int temp2 = raw[i] &0xff;
raw[i] = (char)(temp2 ^ (key_cs[i&7] &0xff) ^ temp);
temp = raw[i];
}
int old = key_cs[0] &0xff;
old |= key_cs[1] << 8 &0xff00;
old |= key_cs[2] << 0x10 &0xff0000;
old |= key_cs[3] << 0x18 &0xff000000;
old += size;
key_cs[0] = (char)(old &0xff);
key_cs[1] = (char)(old >> 0x08 &0xff);
key_cs[2] = (char)(old >> 0x10 &0xff);
key_cs[3] = (char)(old >> 0x18 &0xff);
}
void Decode(char *input, int size) {
int i = 0;
int j = 0;
for(int k=0; k < size; k++) {
int i1 = input[k] & 0xFF;
input[k] = (char)(i1 ^ key_sc[j++] & 0xFF ^i);
i = i1;
if(j>7) j=0;
}
long l = key_sc[0] & 0xFF;
l |= key_sc[1] << 8 & 0xFF00;
l |= key_sc[2] << 16 & 0xFF0000;
l |= key_sc[3] << 24 & 0xFF000000;
l += size;
key_sc[0] = (char)(l & 255L);
key_sc[1] = (char)(l >> 8 & 255L);
key_sc[2] = (char)(l >> 16 & 255L);
key_sc[3] = (char)(l >> 24 & 255L);
}
void Key(char* packet, int len) {
key_sc[0] = packet[4];
key_sc[1] = packet[5];
key_sc[2] = packet[6];
key_sc[3] = packet[7];
key_sc[4] = (char)0xA1;
key_sc[5] = (char)0x6C;
key_sc[6] = (char)0x54;
key_sc[7] = (char)0x87;
for(i=0;i<8;i++) {
key_cs[i] = key_sc[i];
}
}
// вычисляет чексумму и вставляет её в пакет
// как пользоватся: add_ckecksum(CelyjPaket+2, DlinaPaketa-(2+4+4));
void add_ckecksum(unsigned char *raw, int count) {
unsigned long chksum = 0;
unsigned long ecx;
int i = 0;
for(i = 0; i < count; i += 4) {
ecx = (unsigned long)raw[i];
ecx |= (unsigned long)raw[i + 1]<<8;
ecx |= (unsigned long)raw[i + 2]<<16;
ecx |= (unsigned long)raw[i + 3]<<24;
chksum ^= ecx;
}
memcpy(raw+count, (char *)&chksum, 4);
}
void RSAKeyDecode(char* RSAKey) {
for (int i = 0; i < 64; i++) {
RSAKey[i + 64] ^= RSAKey[i];
}
for (int i = 0; i < 4; i++) {
RSAKey[i + 13] ^= RSAKey[i + 52];
}
for (int i = 0; i < 64; i++) {
RSAKey[i] ^= RSAKey[i + 64];
}
for (int i = 0; i < 4; i++) {
BYTE tmp = RSAKey[i];
RSAKey[i] = RSAKey[i + 77];
RSAKey[i + 77] = tmp;
}
}
Вспомогательные методы - Шифрация пакетов GameServer (TechnoWiz@rd)
Оффтоп
Код:
Каждый пакет состоит из размера пакета (2 байта), типа пакета (1 байт) и блока параметров (переменная длина). В дополнение к этому, в пакетах Login-Server, в конце добавляется контрольная сумма и дополняется нулями так, чтобы размер пакета был кратен 8-ми байтам. Контрольная сумма может быть рассчитана следующей функцией:
unsigned long checksum( unsigned char *packet, int count ) {
long chksum = 0L;
for( int i = 0; i < count; i += 4 )
chksum ^= *((unsigned long *)&raw[i]);
return chksum;
};
Все последующие пакеты будут шифроваться динамическим BlowFish ключом. Пакет LoginRequest дополнительно шифруется по алгоритму RSA. Ключ состоит из следующих частей: B = 1024, E = 65537, N = передается в пакете Init. Вместе эти 3 части составляют целый RSA ключ. Байты N в пакете зашифрованы функцией:
void scrambleMod( char *n ) {
typedef unsigned char byte;
int i;
for( i=0; i<4; i++ ) {
byte temp = n[0x00 + i];
n[0x00 + i] = n[0x4d + i];
n[0x4d + i] = temp;
};
// step 2 xor first 0x40 bytes with last 0x40 bytes
for( i=0; i<0x40; i++ ) {
n[i] = (byte)(n[i] ^ n[0x40 + i]);
};
// step 3 xor bytes 0x0d-0x10 with bytes 0x34-0x38
for( i=0; i<4; i++ ) {
n[0x0d + i] = (byte)(n[0x0d + i] ^ n[0x34 + i]);
};
// step 4 xor last 0x40 bytes with first 0x40 bytes
for( i=0; i<0x40; i++ ) {
n[0x40 + i] = (byte)(n[0x40 + i] ^ n[i]);
};
};
Для расшифровки можно воспользоваться следующей функцией:
void unscrambleMod( char *n )
{
typedef unsigned char byte;
int i;
// step 4 xor last 0x40 bytes with first 0x40 bytes
for( i=0; i<0x40; i++ ) {
n[0x40 + i] = (byte)(n[0x40 + i] ^ n[i]);
};
// step 3 xor bytes 0x0d-0x10 with bytes 0x34-0x38
for( i=0; i<4; i++ ) {
n[0x0d + i] = (byte)(n[0x0d + i] ^ n[0x34 + i]);
};
// step 2 xor first 0x40 bytes with last 0x40 bytes
for( i=0; i<0x40; i++ ) {
n[i] = (byte)(n[i] ^ n[0x40 + i]);
};
for( i=0; i<4; i++ ) {
byte temp = n[0x00 + i];
n[0x00 + i] = n[0x4d + i];
n[0x4d + i] = temp;
};
};
Для шифрования пакетов Game-Server используется алгоритм XOR. Ключ XOR генерируется случайно и передается клиенту в пакете CryptInit. Функции шифрования и дешифрации приведены ниже:
/* Декодирует данные */
void decrypt( unsigned char *data, unsigned int len, unsigned char *Key ){
int temp = 0;
for( unsigned int i = 0; i < len; ++i ) {
int temp2 = data[i] & 0xff;
data[i] = (temp2 ^ (Key[i & 15] & 0xff) ^ temp);
temp = temp2;
};
int old = Key[8] & 0xff;
old |= (Key[9] << 0x08) & 0xff00;
old |= (Key[10] << 0x10) & 0xff0000;
old |= (Key[11] << 0x18) & 0xff000000;
old += len;
Key[8] = old &0xff;
Key[9] = (old >> 0x08) & 0xff;
Key[10] = (old >> 0x10) & 0xff;
Key[11] = (old >> 0x18) & 0xff;
};
/* Кодирует данные */
void encrypt( unsigned char *data, unsigned int len, unsigned char *Key ){
int temp = 0;
for( unsigned int i = 0; i < len; i++) {
int temp2 = data[i] & 0xff;
data[i] = (temp2 ^ (Key[i & 15] & 0xff) ^ temp);
temp = data[i];
};
int old = Key[8] & 0xff;
old |= (Key[9] << 0x08) & 0xff00;
old |= (Key[10] << 0x10) & 0xff0000;
old |= (Key[11] << 0x18) & 0xff000000;
old += len;
Key[8] = old &0xff;
Key[9] = (old >> 0x08) & 0xff;
Key[10] = (old >> 0x10) & 0xff;
Key[11] = (old >> 0x18) & 0xff;
};
С каждым кодированным/декодированным пакетом ключ изменяется на длину пакета, поэтому нужно использовать два отдельных экземпляра ключа – один для шифрования исходящих пакетов, второй для расшифровки входящих.
Все пакеты шифруются начиная с 3-го байта, т.е. размер пакета никогда не шифруется.
Может ктото поделиться порядком подключения на ЛС/ГС по-байтно, что делается с каждым байтом?
Может кто поделиться рабочим примером кода подключения к ЛС/ГС? можно в личку если что