Давно меня здесь не было, но как видите столкнулся с сервером на котором применяется данный вид защиты.
Внимание все изложенное ниже мои догадки, это не значит что все на самом деле происходит так как я описал.
Начнем с того что я решил напомнить себе про L2, поиграл, побегал, надоело решил "пошаманить" с "заточками"(спасибо NLObP ещё раз за твой труд) но увы, вместо знакомых пакетов увидел нечто что ввело меня в ступор... отвлекся.
Во первых если я верно понял то для сервера и клиента используются разные ключи.
l
Код:
package com.lameguard.crypt;
import com.lameguard.Config;
import com.lameguard.crypt.impl.L2C;
import com.lameguard.crypt.impl.L2S;
import com.lameguard.crypt.impl.VMPC;
public class GameCrypt
{
public GameCrypt()
{
isEnabled = false;
isProtected = true;
}
public void setProtected(boolean state)
{
isProtected = state;
}
public void setKey(byte key[])
{
if(isProtected)
{
c = new VMPC();
c.setup(key, Config.LAMEGUARD_CLIENT_CRYPT_IV);
s = ((LameCrypt) (Config.LAMEGUARD_USE_DEFAULT_ENCODER ? ((LameCrypt) (new L2S())) : ((LameCrypt) (new VMPC()))));
s.setup(key, Config.LAMEGUARD_SERVER_CRYPT_IV);
} else
{
c = new L2C();
c.setup(key, null);
s = new L2S();
s.setup(key, null);
}
}
public void decrypt(byte raw[], int offset, int size)
{
if(isEnabled)
c.crypt(raw, offset, size);
}
public void encrypt(byte raw[], int offset, int size)
{
if(isEnabled)
s.crypt(raw, offset, size);
else
isEnabled = true;
}
private LameCrypt c;
private LameCrypt s;
private boolean isEnabled;
private boolean isProtected;
}
Отсюда видно что если Администратор задал ключи в конфиге то их используют, иначе используется упрошенная схема шифрования
Дальше;
Код:
package com.lameguard.crypt.impl;
import com.lameguard.crypt.LameCrypt;
public class VMPC
implements LameCrypt
{
public VMPC()
{
n = 0;
P = new byte[256];
s = 0;
}
public void setup(byte key[], byte iv[])
{
s = 0;
for(int i = 0; i < 256; i++)
P[i] = (byte)(i & 0xff);
for(int m = 0; m < 768; m++)
{
s = P[s + P[m & 0xff] + key[m % 64] & 0xff];
byte temp = P[m & 0xff];
P[m & 0xff] = P[s & 0xff];
P[s & 0xff] = temp;
}
for(int m = 0; m < 768; m++)
{
s = P[s + P[m & 0xff] + iv[m % 64] & 0xff];
byte temp = P[m & 0xff];
P[m & 0xff] = P[s & 0xff];
P[s & 0xff] = temp;
}
for(int m = 0; m < 768; m++)
{
s = P[s + P[m & 0xff] + key[m % 64] & 0xff];
byte temp = P[m & 0xff];
P[m & 0xff] = P[s & 0xff];
P[s & 0xff] = temp;
}
n = 0;
}
public void crypt(byte raw[], int offset, int size)
{
for(int i = 0; i < size; i++)
{
s = P[s + P[n & 0xff] & 0xff];
byte z = P[P[P[s & 0xff] & 0xff] + 1 & 0xff];
byte temp = P[n & 0xff];
P[n & 0xff] = P[s & 0xff];
P[s & 0xff] = temp;
n = (byte)(n + 1 & 0xff);
raw[offset + i] = (byte)(raw[offset + i] ^ z);
}
}
private byte n;
private byte P[];
private byte s;
}
Затрудняюсь описать операции так как не силен в яве но по видимому этот фрагмент кода генерирует ключ(поправьте если не прав) из lameguard.Config а именно из этого фрагмента
Код:
byte key[] = attrs.getValue("Client-Key").getBytes();
byte tmp[] = new byte[32];
System.arraycopy(key, 0, tmp, 0, 32);
LAMEGUARD_CLIENT_CRYPT_KEY = LameKey.expandKey(tmp, 32);
System.arraycopy(key, 32, tmp, 0, 32);
LAMEGUARD_CLIENT_CRYPT_IV = LameKey.expandKey(tmp, 32);
key = attrs.getValue("Server-Key").getBytes();
System.arraycopy(key, 0, tmp, 0, 32);
LAMEGUARD_SERVER_CRYPT_KEY = LameKey.expandKey(tmp, 32);
System.arraycopy(key, 32, tmp, 0, 32);
LAMEGUARD_SERVER_CRYPT_IV = LameKey.expandKey(tmp, 32);
который в свою очередь расширяется по алгоритму из этого фрагмента LameKey.expandKey....