Показать сообщение отдельно
Непрочитано 27.06.2019, 06:46   #2
Пользователь

По умолчанию Re: Порядок авторизации

Почитать на тему:
Свернуть ↑Развернуть ↓

Серверов два — сервер авторизации и сервер игры. Каждый из них шифрует пакеты для клиента немного по-своему

Поскольку в ответ на 0x00 (Init) ожидается ответ 0x07 (AuthGameGuard), значит речь идет о сервере авторизации. Рассмотрим общение с клиентом на примере сервера авторизации версии c621


Общие сведения
  • Сервер авторизации версии c621 совместим с клиентами Chaotic Throne (включая и Interlude, и High Five), а так же, возможно, и с другими
  • Если клиент получит от сервера неправильный пакет, он зависнет, кританет или не сделает ничего. Никаких уведомлений клиент не присылает
  • Пакеты представляют собой массивы байтов
  • В TCP-сокет байты приходят и записываются в обратном порядке (см. Little Endian)
  • Пакеты состоят из длины (2 байта), типа пакета (1 байт) и содержимого (любое число байтов)
  • Содержимым пакета будем называть именно данные, передаваемые в пакете (ключи, ID сессии и т.д.), исключая длину и тип пакета
  • Длина пакета не шифруется и не учитывается при подсчёте контрольной суммы, поскольку вычисляется после. Тип пакета, как и содержимое, учитывается при подсчёте контрольной суммы. Тип пакета, содержимое и контрольная сумма шифруются вместе по алгоритму Blowfish
  • Длина пакета — число, обозначающее длину всего пакета. Иными словами, в нее включаются и длина зашифрованных данных (которые состоят из содержимого и типа пакета, контрольной суммы и зашифрованы по алгоритму Blowfish) и два байта на само число, указывающее длину
  • Blowfish — блочный алгоритм шифрования, обрабатывает блоками по 8 байт, а значит, длина содержимого пакета вместе с типом и контрольной суммой должна быть кратна 8 (для этого контрольная сумма отбивается от содержимого пакета необходимым количеством нулей)
  • Обратите внимание, в зависимости от того, заранее ли вы собираете пакет в порядке Little Endian или потом разворачиваете алгоритмы шифрования и расчета контрольной суммы будут, соответственно, разными
    Это может быть важно в том случае, если, к примеру, выбранная для вашего языка программирования библиотека Blowfish может шифровать байты только в прямом порядке (Big Endian)


Порядок взаимодействия сервера авторизации с клиентом

Для удобства обозначим префиксом S пакеты, отправляемые сервером, а C — присылаемые клиентом, поскольку они могут иметь одинаковые ID, но разное содержимое

Пакет S/0x00 (Init) не подписывается контрольной суммой, все остальные пакеты подписываются

Пакет S/0x00 (Init) шифруется по алгоритму XOR, все остальные пакеты не шифруются

Все пакеты шифруются по по алгориму Blowfish ключом, случайно генерируемым для каждого подключения и отправляемым в пакете S/0x00 (Init), кроме самого пакета S/0x00 (Init), который шифруется ключом, придуманным разработчиками игры (зашит в клиенте)

Шифрование по алгоритму Blowfish всегда идет последним, т.е.:
Код:
# Шифрование пакета S/0x00 (Init)
data = xor.encrypt(data)
data = blowfish.encrypt(data, STATIC_KEY)

# Шифрование любого другого пакета
data = checksum.sign(data)
data = blowfish.encrypt(data, SESSION_KEY)
Расшифровка всегда идет одинаково:
Код:
# Расшифровка любого входящего пакета
data = blowfish.decrypt(data, SESSION_KEY)
data = checksum.verify(data)
Содержимое пакета C/0x00 (RequestAuthLogin) приходит зашифрованным алгоритмом RSA тем ключом, который сервер отправляет в пакете S/0x00 (Init). Зашифрованным приходит только содержимое, но не длина и не тип пакета. Сам пакет зашифрован как обычно. Содержимое зашифровано дополнительно, т.к. содержит логин и пароль

Порядок взаимодействия при успешной авторизации:
  1. Пользователь вводит логин и пароль, нажимает вход
  2. Клиент подключается к серверу
  3. Сервер отправляет пакет S/0x00 (Init)
  4. Клиент присылает пакет C/0x07 (AuthGameGuard)
  5. Сервер отправляет пакет S/0x0b (GGAuth)
  6. Клиент присылает логин и пароль в пакетe C/0x00 (RequestAuthLogin)
  7. Сервер проверяет логин и пароль и отправляет S/0x03 (LoginOk)
  8. Клиент запрашивает список игровых серверов пакетом C/0x05 (RequestServerList)
  9. Сервер отправляет список игровых серверов в пакете S/0x04 (ServerList)
  10. Пользователь выбирает сервер из списка, нажимает вход
  11. Клиент присылает пакет C/0x02 (RequestServerLogin)
  12. Сервер отправляет пакет S/0x07 (PlayOK)
Далее клиент отключается от сервера авторизации и подключается к игровому серверу


Отправка пакетов сервером авторизации

Пакеты записываются в виде массива байтов:
  1. Записываем 1 байт типа пакета, например, 0x00
  2. Формируем и дописываем содержимое пакета (ID сессии, версию сервера, ключи, нулевой байт окончания ключа Blowfish и т.д.)
  3. Вычисляем контрольную сумму для текущего массива байт
  4. Добиваем длину текущего массива байт нулевыми байтами до кратной 8
  5. Дописываем контрольную сумму в массив
  6. Шифруем текущий массив байт по алгоритму Blowfish
  7. Вычисляем длину получившегося массива
  8. Прибавляем к значению длины 2 для учета самих двух байтов длины
  9. Дописываем длину в начало массива
В TCP-сокет байты следует записывать в обратном порядке


Получение пакетов сервером авторизации

Пакеты считываются из массива байтов:
  1. Считываем 2 байта длины пакета
  2. Вычитаем 2 из значения длины, чтобы отсечь байты самой длины
  3. Считываем получившееся число байт в отдельный массив для данных
  4. Расшифровываем байты данных по алгоритму Blowfish
  5. Вычисляем и сверяем контрольную сумму
  6. Отсекаем один байт с типом пакета
  7. Разбираем байты содержимого
Из TCP-сокета байты следует считывать в обратном порядке

Последний раз редактировалось freelu; 27.06.2019 в 23:59.
freelu вне форума Ответить с цитированием