Вернуться   CoderX :: Forums > Основные форумы > Программинг
Войти через OpenID

Программинг Форум для тем связанных с программированием

Чат (Новых сообщений с момента вашего последнего визита нет)
Загрузка...
Задавайте ваши вопросы на форуме. Чат предназначен для небольших разговоров.
 
Ответ
 
Опции темы Опции просмотра
Старый 15.03.2015, 21:41   #1
Новичок
 
Аватар для noklin
 
Регистрация: 15.03.2015
Сообщений: 6
Сказал Спасибо: 1
Имеет 0 спасибок в 0 сообщенях
noklin пока неопределено
По умолчанию Проблема с BlowFish

Получаю от сервера Init пакет 186 байт:

ba 00 8c 22 e3 95 ee 6e b5 71 57 80 e3 c9 b8 cf
44 23 41 39 19 c4 35 36 11 3a 87 12 6d ac 22 14
92 4d d3 04 6e 91 32 aa 44 cb 17 69 8f 65 48 0b
f8 6d dc c7 d8 09 9d 07 da fd 50 66 da 97 05 24
e5 ee ef 3b da cd 6f 82 a3 a3 73 64 6b b2 01 92
39 2e 0d b4 f1 16 03 e0 aa db ab 0a b4 af 05 9a
c0 01 a9 59 40 cb 49 10 e6 b7 c9 15 3a c5 b2 b0
2a 68 cc 00 6a 2c ad 7a d2 3d 4f 9d 76 8b ad 71
cd 7b 31 59 7f 24 c8 1d 09 16 b1 12 c0 8b 9b 35
6b 21 86 d0 8b 54 39 0b 31 46 e6 36 75 fc 62 b2
17 40 99 c6 8b cb 72 78 4f b4 6b 77 d5 5a ba ea
14 65 9f 5c 4c a0 6c 01 d9 e7

Затем пытаюсь расшифровывать:
1. Беру первые 8 байт начиная с 3-его (8c 22 e3 95 ee 6e b5 71)
2. Делю их на подблоки. L = 8c 22 e3 95; R = ee 6e b5 71;
и так далее по алгоритму расшифровки.


Вопросы:
1. Размер блока и в правду должен быть 8 байт?
2. Нужно ли делать еще какие нибудь манипуляции с байтами до расшифровки?
noklin вне форума   Ответить с цитированием
Старый 16.03.2015, 15:29   #2
Местный
 
Аватар для ScythLab
 
Регистрация: 24.10.2014
Сообщений: 190
Сказал Спасибо: 4
Имеет 42 спасибок в 40 сообщенях
ScythLab пока неопределено
По умолчанию

Ты сам пишешь алгоритм blowfish? Если брать готовые модули, то они как правило работают с потоком данных, а внутри сами разделяют по блокам.
До расшифровки ничего с данными делать не нужно, а вот после для некоторых пакетов (возможно как раз для Init) требуется дексорирование.
__________________
Хобби: разработка бота для Lineage.
ScythLab вне форума   Ответить с цитированием
Старый 16.03.2015, 17:42   #3
Новичок
 
Аватар для noklin
 
Регистрация: 15.03.2015
Сообщений: 6
Сказал Спасибо: 1
Имеет 0 спасибок в 0 сообщенях
noklin пока неопределено
По умолчанию

Цитата:
Сообщение от ScythLab Посмотреть сообщение
Ты сам пишешь алгоритм blowfish?
Да. Точнее писал, пока не наткнулся на готовое решение в сорцах сборки l2jskyline.ru.
Так вот там, там есть метод:

private void decryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex){

int xl = BytesTo32bits(src, srcIndex);
int xr = BytesTo32bits(src, srcIndex + 4);

xl ^= P[ROUNDS + 1];

for (int i = ROUNDS; i > 0; i -= 2){
xr ^= F(xl) ^ P[i];
xl ^= F(xr) ^ P[i - 1];
}

xr ^= P[0];

Bits32ToBytes(xr, dst, dstIndex);
Bits32ToBytes(xl, dst, dstIndex + 4);
}

Он работает с массивами байт из одного читает->расшифровывает а в другой записывает и главное что есть индекс начального байта с которого начинают работу как для массива из которого читают , так и для массива в который пишут. Из этого складывается мысль что для конкретного пакета существует свой алгоритм или такая архитектура связана с механизмом формирования пакета.

Я ваще думаю что байты инвертировать надо в пакете.
Всем известный факт: 2 первых байта это размер пакета. Так? Да окей берем 2 байта BA00 читаем как в школе учили слева на право: 1011101000000000 а это у нас ваще -17920(в десятичной системе) Отсюда мысль про ивертирование. По моей гипотезе нужно брать по порядку значимые байты и их инвертировать. То есть зная что 2 байта есть размер пакета, мы берем и инвертируем это 2 байта получаем 00BA. Следующий байт 8С тип пакета его не трогаем. Следующие 4 байта ID сессии его тоже инвертируем и так далее. А потом применить мой BlowFish без первых 2х байт конечно же.

Копался в исходниках но нечего похожего на это не нашел.

Последний раз редактировалось noklin, 16.03.2015 в 17:55.
noklin вне форума   Ответить с цитированием
Старый 16.03.2015, 22:42   #4
Местный
 
Аватар для ScythLab
 
Регистрация: 24.10.2014
Сообщений: 190
Сказал Спасибо: 4
Имеет 42 спасибок в 40 сообщенях
ScythLab пока неопределено
По умолчанию

Не нужно ничего инвертировать, инвертирование тебе нужно только чтобы число (размером более 1 байта), которое ты видишь в потоке, например корректно вбить его в калькулятор.
Тебе нужно раскодировать пакет с помощью BlowFish (с блоками сам определяйся), потом по какому-то принципу провести дексорирование (если нужно) и получишь готовый пакет.
Если готовый пакет не получается, то возможно 3 варианта:
1) ошибка в BlowFish
2) ошибка в дексорировании
3) на сервере установлена нестандартная защита
__________________
Хобби: разработка бота для Lineage.
ScythLab вне форума   Ответить с цитированием
Старый 17.03.2015, 03:30   #5
Новичок
 
Аватар для noklin
 
Регистрация: 15.03.2015
Сообщений: 6
Сказал Спасибо: 1
Имеет 0 спасибок в 0 сообщенях
noklin пока неопределено
По умолчанию

Алилуя! Проблема решена!
Покопался поглубже в исходниках. Нашел класс LoginCrypt в нем метод ecrypt(массив, смещение, и размер) который обращался к методу decrypt(массив, смещение, и размер) Объекта NewCrypt

public void decrypt(byte raw[], int offset, int size) throws IOException
{
byte result[] = new byte[size];
int count = size / 8;
for(int i = 0; i < count; i++)
_decrypt.processBlock(raw, offset + i * 8, result, i * 8);

System.arraycopy(result, 0, raw, offset, size);
}
Видно, что тут блоки явно по 8 байт.
Берем 8 байт кидаем их в processBlock он в свою очередь вызывает метод decryptBlock(in, inOff, out, outOff);

private void decryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
{
int xl = bytesTo32bits(src, srcIndex);
int xr = bytesTo32bits(src, srcIndex + 4);
xl ^= P[ROUNDS + 1];
for (int i = ROUNDS; i > 0; i -= 2)
{
xr ^= func(xl) ^ P[i];
xl ^= func(xr) ^ P[i - 1];
}
xr ^= P[0];
bits32ToBytes(xr, dst, dstIndex);
bits32ToBytes(xl, dst, dstIndex + 4);
}

А вот и метод где байты инвертируются

private int bytesTo32bits(byte[] b, int i)
{
return ((b[i + 3] & 0xff) << 24) | ((b[i + 2] & 0xff) << 16) | ((b[i + 1] & 0xff) << 8)
| ((b[i] & 0xff));
}
На выходе инвертируются обратно:

private void bits32ToBytes(int in, byte[] b, int offset)
{
b[offset] = (byte) in;
b[offset + 1] = (byte) (in >> 8);
b[offset + 2] = (byte) (in >> 16);
b[offset + 3] = (byte) (in >> 24);
}

Проблемы была в том что я на входе ничего не инвертировал.
Пользовался вместо вышеуказанного метода bytesTo32bits
таким:

private int BytesTo32bits(byte[] b, int i)
{
return ((b[i] & 0xff) << 24) | ((b[i + 1] & 0xff) << 16) | ((b[i + 2] & 0xff) << 8) | ((b[i + 3] & 0xff));
}
noklin вне форума   Ответить с цитированием
Ответ

  CoderX :: Forums > Основные форумы > Программинг



Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +4, время: 20:19.

vBulletin style designed by MSC Team.
Powered by vBulletin® Version 3.6.11
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Locations of visitors to this page
Rambler's Top100

Вы хотите чувствовать себя в безопасности? чоп Белган обеспечит её!