» » » Реализация нового транспортного протокола NTCP2 сети I2P

 

Реализация нового транспортного протокола NTCP2 сети I2P

Автор: admin от 13-08-2018, 00:05, посмотрело: 21

Транспортные протоколы I2P были разработаны почти 15 лет назад, когда основной задачей было сокрытие содержимого трафика, а не факт использования того или иного протокола. dpi и блокировку трафика в то время никто не принимал в расчет. Однако времена меняются и хотя существующие протоколы I2P по прежнему защищены довольно хорошо, возникла необходимость в новом транспортном протоколе, отвечающему на существующие и будущие угрозы, и, в первую очередь, dpi, анализирующий длину пакетов. Помимо этого, новый протокол использует самые современные достижения криптографии. Полное описание протокола здесь. За основу взят Noise, в котором в качестве хэш-функции используется SHA256, а в качестве DH (в терминологии Noise) — x25519.



Реализация нового транспортного протокола NTCP2 сети I2P

Jeff Becker-ом, известным в I2P как psi.

По сравнению с NTCP x25519 заменяет DH, AEAD/Chaha20/Poly1305 заменяет AES-256-CBC/Adler32, а Siphash используется для шифрования длины передаваемых сообщений. Процедура вычисления общего ключа стала более сложной: с множеством вызовов HMAC-SHA256.



Изменения в RouterInfo



Для работы по протоколу NTCP2 в дополнение к двум уже существующим ключам (шифрования и подписи) вводится третий ключ x22519, называемый статическим ключем, который обязательно должен присутствовать в каком нибудь адресе RouterInfo как параметр «s» и для клиентов и для серверов. Если более одного адреса поддерживают NTCP2, например ipv4 и ipv6, то «s» обязан быть везде одинаковым. Для клиентов адрес может содержать только «s» и не содержать параметры «host» и «port». Также обязательным параметром NTCP2 является «v», в настоящий момент всегда равный «2».

Адрес NTCP2 может задаваться как адрес типа «NTCP» с дополнительными параметрами — в этом случае соединение может быть установлено как по NTCP так и по NTCP2, или же как адрес типа «NTCP2», поддерживающий только NTCP2 соединения. В джавовском I2P применяется первый способ, в i2pd — второй.

Если узел принимает входящие NTCP2 соединения, то он должен опубликовать параметр «i» со значением IV для шифрования публичного ключа при установке соединения.



Установка соединения



В процессе установки соединения стороны генерируют пары временных ключей x25519, и на основе их и статических ключей вычисляют наборы ключей для передачи данных. Также происходит проверка подлинности статических ключей и соответствие содержимому RouterInfo.

Стороны обмениваются тремя сообщениями:



SessionRequest ------------------

< — SessionCreated

SessionConfirmed ----------------



для каждого из которых вычисляется общий ключ x25519. называемый «input key material», и затем генерируется ключ шифрования сообщения с помощью операции MixKey, при этом значением ck (chaining key) сохраняется между сообщениями и является результатом, на основе которого вычисляются ключи для передачи данных. Реализация MixKey выглядит примерно так:



SessionRequest состоит из 32-х байтного публичного ключа x25519 клиента, и зашифрованного AEAD/Chacha20/Poly1305 16 байтного блока данных + 16 байт хэша, а также набор случайных данных (padding), длина которого передается в зашифрованном блоке. Также там передается длина второй половины сообщения SessionConfirmed. Блок шифруется и подписывается ключем на основе временного ключа клиента и статического ключа сервера. Начальный ck для MixKey устанавливается в SHA256 («Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256»)

Поскольку 32 байта публичного ключа x25519 могут быть распознаны dpi, то они шифруются с помощью AES-256-CBC, где ключем служит хэш адреса сервера, а IV берется из параметра «i» адреса в RouterInfo.



SessionCreated по структуре аналогично SessionRequest, за исключением того, что ключ вычисляется на основе временных ключей обеих сторон, а для IV для шифрования/расшифровки публичного ключа является IV после расшифровки/шифрования публичного ключа из SessionRequest.



SessionConfirmed состоит из двух частей: статический публичный ключ клиента и RouterInfo клиента. В отличие от предыдущих сообщений, публичный ключ шифруется AEAD/Chaha20/Poly1305 с тем же ключем, что и SessionCreated. Поэтому длина первой части не 32, а 48 байт. Вторая часть шифруется тоже AEAD/Chaha20/Poly1305, но с новым ключем, вычисляем на основе временного ключа сервера и статического ключа клиента. Также к RouterInfo может быть добавлен блок случайных данных, но, как правило, в этом нет необходимости, потому что длина RouterInfo разная.



Генерация ключей для передачи данных



Если все проверки хэшей и ключей в процессе установки соединения прошли успешно, то после последнего MixKey на обеих сторонах должен быть одинаковый ck, из которого будут сгенерированы 2 набора троек ключей в каждую сторону свой, где k — ключ AEAD/Chaha20/Poly1305, sipk — ключ для Siphash, sipiv — начальное значение IV для Siphash, которое изменяется после каждого его применения.



Первые 16 байт массива sipkeys представляют собой собой ключ Siphash, вторые 8 байт — IV.

На самом деле для Siphash требуется два ключа по 8 байт, но в i2pd они рассматриваются как 1 ключ длиной 16 байт.



Передача данных



Данные передаются фреймами, каждый фрейм состоит из 3-х частей:




  • 2 байта длины фрейма, зашифрованной Siphash

  • данные, зашифрованные Chacha20

  • 16 байт хэша Poly1305



  • Максимальная длина передаваемых данных в одном фрейме — 65519 байт.

    Длина сообщения шифруется применением операции XOR с первым двумя байтами текущего IV Siphash.

    Данные состоят из блоков, каждому блоку предшествует 3-х байтный заголовок с типом блока и длиной. В основном передаются блоки типа I2NP, содержащие сообщения I2NP с измененным заголовком. В одном фрейме может быть передано несколько I2NP блоков.

    Другим важным типом блока является блок случайных данных, который рекомендуется добавлять к каждому фрейму. Он может быть только один и последним.

    Кроме них, в текущей реализации NTCP2 встречаются еще 3 типа блока:

    RouterInfo — обычно содержит RouterInfo сервера сразу после установки соединения, но может быть передано и RouterInfo произвольного узла в любой момент с целью ускорения работы floodfill-ов, для чего в сообщении предусмотрено поле флагов.

    Termination — отсылается узлом при разрыве соединения по его инициативе с указанием причины.

    DateTime — текущее время в секундах.



    Таким образом, новый транспортный протокол позволяет не только эффективно противостоять dpi, но существенно снижает нагрузку на процессор за счет более современной и быстрой и криптографии, что особенно важно при работе на слабых устройствах типа смартфонов и маршрутизаторах. В настоящий момент поддержка NTCP2 полностью реализована как в официальном I2P, так и в i2pd и появится официально в следующих релизах 0.9.36 и 2.20 соответственно. Для включения ntcp2 в i2pd следует указать конфигурационный параметр ntcp2.enabled=true, и ntcp2.published=true и ntcp2.port= для входящих соединений.

    Источник: Хабр / Интересные публикации

    Категория: Криптография

    Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
    Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

    Добавление комментария

    Имя:*
    E-Mail:
    Комментарий:
    Полужирный Наклонный текст Подчеркнутый текст Зачеркнутый текст | Выравнивание по левому краю По центру Выравнивание по правому краю | Вставка смайликов Выбор цвета | Скрытый текст Вставка цитаты Преобразовать выбранный текст из транслитерации в кириллицу Вставка спойлера
    Введите два слова, показанных на изображении: *