Этот перевод был создан с помощью машинного обучения и может быть не на 100% точным. Просмотреть английскую версию

Спецификация создания туннелей (ElGamal)

Устаревшая спецификация построения tunnel на основе ElGamal, заменена на X25519

Обзор

ПРИМЕЧАНИЕ: УСТАРЕЛО - Это спецификация построения tunnel с использованием ElGamal. Смотрите спецификацию построения tunnel X25519 для текущего метода.

Данный документ описывает детали зашифрованных сообщений построения tunnel, используемых для создания tunnel с помощью метода “неинтерактивного телескопирования”. См. документ по построению tunnel [TUNNEL-IMPL] для обзора процесса, включая методы выбора и упорядочивания узлов.

Создание tunnel осуществляется с помощью одного сообщения, передаваемого по пути узлов в tunnel, переписываемого на месте и отправляемого обратно создателю tunnel. Это единственное tunnel сообщение состоит из переменного количества записей (до 8) - по одной для каждого потенциального узла в tunnel. Отдельные записи асимметрично (ElGamal [CRYPTO-ELG]) зашифрованы для чтения только определенным узлом на пути, в то время как дополнительный симметричный уровень шифрования (AES [CRYPTO-AES]) добавляется на каждом переходе, чтобы раскрыть асимметрично зашифрованную запись только в подходящий момент.

Количество записей

Не все записи должны содержать действительные данные. Сообщение сборки для 3-hop tunnel, например, может содержать больше записей, чтобы скрыть фактическую длину tunnel от участников. Существует два типа сообщений сборки. Оригинальное Tunnel Build Message ([TBM]) содержит 8 записей, что более чем достаточно для любой практической длины tunnel. Более новое Variable Tunnel Build Message ([VTBM]) содержит от 1 до 8 записей. Инициатор может балансировать между размером сообщения и желаемой степенью сокрытия длины tunnel.

В текущей сети большинство tunnel имеют длину 2 или 3 hop. Текущая реализация использует 5-записный VTBM для построения tunnel длиной 4 hop или меньше, и 8-записный TBM для более длинных tunnel. 5-записный VTBM (который при фрагментации помещается в три 1KB tunnel сообщения) снижает сетевой трафик и увеличивает успешность построения, поскольку меньшие сообщения реже теряются.

Ответное сообщение должно быть того же типа и длины, что и сообщение сборки.

Спецификация записи запроса

Также указано в спецификации I2NP [BRR].

Открытый текст записи, видимый только запрашиваемому узлу:

bytes     0-3: tunnel ID to receive messages as, nonzero
bytes    4-35: local router identity hash
bytes   36-39: next tunnel ID, nonzero
bytes   40-71: next router identity hash
bytes  72-103: AES-256 tunnel layer key
bytes 104-135: AES-256 tunnel IV key
bytes 136-167: AES-256 reply key
bytes 168-183: AES-256 reply IV
byte      184: flags
bytes 185-188: request time (in hours since the epoch, rounded down)
bytes 189-192: next message ID
bytes 193-221: uninterpreted / random padding

Поля next tunnel ID и next router identity hash используются для указания следующего узла в tunnel, однако для конечной точки исходящего tunnel они указывают, куда должно быть отправлено переписанное сообщение ответа на создание tunnel. Кроме того, next message ID указывает идентификатор сообщения, который должно использовать сообщение (или ответ).

Ключ слоя tunnel, ключ IV tunnel, ключ ответа и IV ответа — это случайные 32-байтовые значения, генерируемые создателем для использования только в этой записи запроса построения.

Поле flags содержит следующее:

Bit order: 76543210 (bit 7 is MSB)
bit 7: if set, allow messages from anyone
bit 6: if set, allow messages to anyone, and send the reply to the
       specified next hop in a Tunnel Build Reply Message
bits 5-0: Undefined, must set to 0 for compatibility with future options

Бит 7 указывает, что узел будет входящим gateway (IBGW). Бит 6 указывает, что узел будет исходящей конечной точкой (OBEP). Если ни один из битов не установлен, узел будет промежуточным участником. Оба бита не могут быть установлены одновременно.

Создание записи запроса

Каждый hop получает случайный Tunnel ID, ненулевой. Заполняются Tunnel ID текущего и следующего hop. Каждая запись получает случайный tunnel IV ключ, reply IV, layer ключ и reply ключ.

Шифрование записи запроса

Эта запись в открытом виде шифруется по алгоритму ElGamal 2048 [CRYPTO-ELG] с использованием публичного ключа шифрования узла и форматируется в запись размером 528 байт:

bytes   0-15: First 16 bytes of the SHA-256 of the current hop's router identity
bytes 16-527: ElGamal-2048 encrypted request record

В 512-байтовой зашифрованной записи данные ElGamal содержат байты 1-256 и 258-513 из 514-байтового зашифрованного блока ElGamal [CRYPTO-ELG]. Два байта заполнения из блока (нулевые байты в позициях 0 и 257) удаляются.

Поскольку открытый текст использует полное поле, нет необходимости в дополнительном заполнении сверх SHA256(cleartext) + cleartext.

Каждая 528-байтовая запись затем итеративно шифруется (используя AES дешифрование с ключом ответа и IV ответа для каждого hop’а), так что идентичность router’а будет в открытом тексте только для соответствующего hop’а.

Обработка и шифрование переходов

Когда узел получает TunnelBuildMessage, он просматривает содержащиеся в нем записи в поисках той, которая начинается с их собственного хеша идентичности (обрезанного до 16 байт). Затем он расшифровывает блок ElGamal из этой записи и извлекает защищенный открытый текст. В этот момент они убеждаются, что запрос tunnel не является дубликатом, подавая ключ ответа AES-256 в фильтр Блума. Дубликаты или недействительные запросы отбрасываются. Записи, которые не помечены текущим часом или предыдущим часом, если это вскоре после начала часа, должны быть отброшены. Например, возьмите час из временной метки, преобразуйте в полное время, затем если это более чем на 65 минут позади или на 5 минут впереди текущего времени, это недействительно. Фильтр Блума должен иметь продолжительность не менее одного часа (плюс несколько минут, чтобы учесть расхождение часов), так чтобы дублирующиеся записи в текущем часе, которые не отклоняются проверкой временной метки часа в записи, будут отклонены фильтром.

После принятия решения о том, согласятся ли они участвовать в tunnel или нет, они заменяют запись, которая содержала запрос, на зашифрованный блок ответа. Все остальные записи шифруются AES-256 [CRYPTO-AES] с включенным ключом ответа и IV. Каждая запись шифруется AES/CBC отдельно с одним и тем же ключом ответа и IV ответа. Режим CBC не продолжается (не связывается) между записями.

Каждый hop знает только свой собственный ответ. Если он согласен, он будет поддерживать tunnel до истечения срока, даже если он не будет использоваться, поскольку не может знать, согласились ли все остальные hop.

Спецификация записи ответа

После того как текущий hop прочитает свою запись, он заменяет её записью ответа, указывающей, согласен ли он участвовать в tunnel или нет, и если не согласен, то классифицирует причину отказа. Это просто значение в 1 байт, где 0x0 означает согласие участвовать в tunnel, а более высокие значения означают более высокие уровни отказа.

Определены следующие коды отклонения:

  • TUNNEL_REJECT_PROBABALISTIC_REJECT = 10
  • TUNNEL_REJECT_TRANSIENT_OVERLOAD = 20
  • TUNNEL_REJECT_BANDWIDTH = 30
  • TUNNEL_REJECT_CRIT = 50

Чтобы скрыть другие причины, такие как выключение router’а, от узлов, текущая реализация использует TUNNEL_REJECT_BANDWIDTH почти для всех отклонений.

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

AES-256-CBC(SHA-256(padding+status) + padding + status, key, IV)

bytes   0-31 : SHA-256 of bytes 32-527
bytes 32-526 : Random padding
byte 527     : Reply value

Это также описано в спецификации I2NP [BRR].

Подготовка сообщения создания tunnel

При создании нового сообщения Tunnel Build Message все записи Build Request Records должны быть сначала построены и асимметрично зашифрованы с использованием ElGamal [CRYPTO-ELG]. Затем каждая запись преждевременно расшифровывается с помощью ключей ответа и IV от узлов, находящихся ранее в пути, используя AES [CRYPTO-AES]. Эта расшифровка должна выполняться в обратном порядке, чтобы асимметрично зашифрованные данные появились в открытом виде на нужном узле после того, как их предшественник их зашифрует.

Избыточные записи, не нужные для отдельных запросов, просто заполняются случайными данными создателем.

Доставка сообщения построения tunnel

Для исходящих tunnel, доставка осуществляется напрямую от создателя tunnel к первому узлу, упаковывая TunnelBuildMessage так, как если бы создатель был просто еще одним узлом в tunnel. Для входящих tunnel доставка осуществляется через существующий исходящий tunnel. Исходящий tunnel обычно берется из того же пула, что и новый строящийся tunnel. Если в этом пуле нет доступного исходящего tunnel, используется исходящий исследовательский tunnel. При запуске, когда исходящего исследовательского tunnel еще не существует, используется фиктивный 0-узловой исходящий tunnel.

Обработка конечной точки сообщения создания tunnel

Для создания исходящего tunnel, когда запрос достигает конечной точки исходящего tunnel (как определено флагом ‘разрешить сообщения для всех’), хоп обрабатывается как обычно, шифруя ответ на месте записи и шифруя все остальные записи, но поскольку нет ‘следующего хопа’ для пересылки TunnelBuildMessage, вместо этого он помещает зашифрованные записи ответов в TunnelBuildReplyMessage ([TBRM]) или VariableTunnelBuildReplyMessage ([VTBRM]) (тип сообщения и количество записей должны соответствовать запросу) и доставляет его в tunnel для ответов, указанный в записи запроса. Этот tunnel для ответов пересылает Tunnel Build Reply Message обратно создателю tunnel, точно так же, как и любое другое сообщение [TUNNEL-OP]. Создатель tunnel затем обрабатывает его, как описано ниже.

Reply tunnel был выбран создателем следующим образом: Обычно это входящий tunnel из того же пула, что и новый исходящий tunnel, который строится. Если во входящий tunnel недоступен в этом пуле, используется входящий исследовательский tunnel. При запуске, когда входящий исследовательский tunnel еще не существует, используется поддельный входящий tunnel с 0 переходов.

Для создания входящего tunnel, когда запрос достигает входящей конечной точки (также известной как создатель tunnel), нет необходимости генерировать явное сообщение Tunnel Build Reply Message, и router обрабатывает каждый из ответов, как описано ниже.

Обработка сообщения ответа на создание tunnel

Для обработки записей ответа создатель должен просто расшифровать каждую запись по отдельности с помощью AES, используя ключ ответа и IV каждого узла в tunnel после пира (в обратном порядке). Это затем раскрывает ответ, указывающий, согласны ли они участвовать в tunnel или почему они отказываются. Если все согласны, tunnel считается созданным и может использоваться немедленно, но если кто-то отказывается, tunnel отбрасывается.

Согласия и отказы записываются в профиле каждого узла [PEER-SELECTION] для использования в будущих оценках пропускной способности tunnel узла.

История и примечания

Эта стратегия возникла во время обсуждения в списке рассылки I2P между Майклом Роджерсом, Мэттью Тоузлендом (toad) и jrandom относительно атаки предшественника. См. [TUNBUILD-SUMMARY], [TUNBUILD-REASONING]. Она была введена в релизе 0.6.1.10 от 2006-02-16, который был последним релизом, в котором было сделано изменение, несовместимое с предыдущими версиями, в I2P.

Примечания:

  • Данная конструкция не препятствует двум враждебным узлам внутри tunnel помечать одну или несколько записей запросов или ответов для обнаружения того, что они находятся в одном tunnel, но это может быть обнаружено создателем tunnel при чтении ответа, что приведет к пометке tunnel как недействительного.

  • Данная схема не включает proof of work (доказательство работы) для асимметрично зашифрованной секции, хотя 16-байтный хеш идентификатора может быть урезан наполовину с заменой последней части функцией hashcash стоимостью до 2^64.

  • Данная схема сама по себе не предотвращает возможность двух враждебных узлов внутри tunnel использовать информацию о времени для определения того, находятся ли они в одном и том же tunnel. Использование пакетной и синхронизированной доставки запросов могло бы помочь (группировка запросов и их отправка в определенную (синхронизированную по ntp) минуту). Однако это позволяет узлам ‘помечать’ запросы, задерживая их и обнаруживая задержку позже в tunnel, хотя возможно отбрасывание запросов, не доставленных в небольшом временном окне, сработало бы (хотя для этого потребовалась бы высокая степень синхронизации часов). В качестве альтернативы, возможно, отдельные переходы могли бы вносить случайную задержку перед пересылкой запроса?

  • Существуют ли нефатальные методы маркировки запроса?

  • Временная метка с точностью до одного часа используется для предотвращения повторных атак. Это ограничение не применялось до выпуска версии 0.9.16.

Будущая работа

  • В текущей реализации инициатор оставляет одну запись пустой для себя. Таким образом, сообщение из n записей может построить только tunnel из n-1 переходов. Это представляется необходимым для входящих tunnel (где предпоследний переход может видеть хеш-префикс для следующего перехода), но не для исходящих tunnel. Это требует исследования и проверки. Если возможно использовать оставшуюся запись без компрометации анонимности, мы должны это сделать.

  • Дальнейший анализ возможных атак меткирования и временных атак, описанных в приведенных выше заметках.

  • Используйте только VTBM; не выбирайте старые узлы, которые его не поддерживают.

  • Build Request Record не указывает время жизни tunnel или срок истечения; каждый hop истекает tunnel через 10 минут, что является жестко закодированной константой для всей сети. Мы могли бы использовать бит в поле флагов и взять 4 (или 8) байт из заполнения, чтобы указать время жизни или срок истечения. Запрашивающий указывал бы эту опцию только если все участники её поддерживают.

Ссылки

Was this page helpful?