Сервер tcp://livid.pp.ru:5278 работает по следующему протоколу:
- При первом запросе сервер возвращает 3 числа, соответствующие генератору, модулю и публичному числу своей стороны по протоколу Диффи-Хеллмана. Каждое – отдельным сообщением (т.е. всего 3 сообщения). Эти сообщения не шифруются.
- Сервер ожидает числа A – публичного числа подключающейся стороны. Это сообщение не шифруется.
- Получив число А, сервер передаёт вектор инициализации для шифрования, длина в битах совпадает с длиной модуля Диффи-Хеллмана. Это сообщение не шифруется. Дальнейшие сообщения шифруются.
- Сервер передаёт число и два вектора: простое число (модуль) m, случайный идентификатор третьей стороны I’ и секретный ключ g в схеме Блома. Каждое – отдельным сообщением (т.е. всего 3 сообщения). Случайный идентификатор генерируется инверсным конгруэнтным генератором с модулем m.
- В виде подтверждения, сервер ожидает число k – ключ для взаимодействия сторон с ключом g и идентификатором I’ в схеме Блома.
- Получив подтверждение, сервер передаёт идентификатор I, соответствующий секретному ключу g, и закрывает соединение.
В случае получения неожиданных данных, сервер закрывает соединение.
Каждое сообщение сжимается по алгоритму Лемпеля-Зива-Уэлча (LZW). Если сообщение шифруется, результат сжатия шифруется с общим ключом, полученным по алгоритму Диффи-Хеллмана, с использованием блочного шифра Цезаря (Виженера с длиной ключа 1 блок) с длиной блока равной длине модуля Диффи-Хеллмана p в режиме обратной связи по выходу (OFB)1. Шифр используется в поточном режиме. Результат шифрования (или сжатия, если сообщение не шифруется) закодирован линейным кодом типа Хэмминга (15, 11) с порождающей матрицей в стандартом виде \[G = \begin{pmatrix} 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 0 \\ 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 0 \\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 1 & 0 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 0 & 1 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 1 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 1 & 1 & 1 \\ \end{pmatrix}\]
G = [
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1],
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1]]
Каждый блок кода Хэмминга дополняется нулём справа до 16 бит.
При передаче данных возможны ошибки!
Задача
- Восстановить секретную матрицу схемы Блома
- Восстановить параметры инверсного конгруэнтного генератора
Формат представления натуральных чисел
Короткие (32 бита)
- 8 бит – 00000000
- 32 бита – двоичное представление числа в форме Little Endian
Длинные (переменная длина)
- 8 бит – 00000001
- 32 бита – n – Количество октетов в представлении числа, натуральное, двоичное представление числа в форме Little Endian
- n*8 бит – двоичное представление числа в форме Little Endian
Формат представления векторов натуральных чисел
- 8 бит – 00000010
- 32 бита – n – количество элементов в векторе, натуральное, двоичное представление числа в форме Little Endian
- n раз – натуральное число в формате, описанном выше.
Обращаю внимание, что это довольно плохой шифр с точки зрения криптографии, но предлагать AES128 не хочется↩︎