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

NTCP (TCP на основе NIO)

Устаревший TCP-транспорт для I2P на основе Java NIO, заменённый на NTCP2

УСТАРЕЛ, БОЛЬШЕ НЕ ПОДДЕРЖИВАЕТСЯ. Отключен по умолчанию с версии 0.9.40 2019-05. Поддержка удалена с версии 0.9.50 2021-05. Заменен на NTCP2 . NTCP это транспорт на основе Java NIO, введенный в релизе I2P 0.6.1.22. Java NIO (новый I/O) не страдает от проблем “1 поток на соединение” старого TCP транспорта. NTCP-over-IPv6 поддерживается начиная с версии 0.9.8.

По умолчанию NTCP использует IP/порт, автоматически обнаруженный SSU. Когда включено в config.jsp, SSU будет уведомлять/перезапускать NTCP при изменении внешнего адреса или статуса брандмауэра. Теперь вы можете включить входящий TCP без статического IP или службы dyndns.

Код NTCP в I2P относительно легковесный (в 4 раза меньше кода SSU), поскольку использует базовый Java TCP транспорт для надежной доставки.

Спецификация адреса router

Следующие свойства хранятся в сетевой базе данных.

  • Название транспорта: NTCP
  • host: IP (IPv4 или IPv6). Сокращённый IPv6-адрес (с “::”) разрешён. Имена хостов ранее были разрешены, но считаются устаревшими начиная с версии 0.9.32. См. предложение 141.
  • port: 1024 - 65535

Спецификация протокола NTCP

Стандартный формат сообщений

После установления соединения транспорт NTCP отправляет отдельные сообщения I2NP с простой контрольной суммой. Нешифрованное сообщение кодируется следующим образом:

+-------+-------+-------+-------+-------+-------+-------+-------+
| sizeof(data)  |                                               |
+-------+-------+                                               +
|                            data                               |
~                                                               ~
|                                                               |
+                                       +-------+-------+-------+
|                                       |        padding
+-------+-------+-------+-------+-------+-------+-------+-------+
                                | Adler checksum of sz+data+pad |
+-------+-------+-------+-------+-------+-------+-------+-------+

Затем данные шифруются с использованием AES/256/CBC. Сеансовый ключ для шифрования согласовывается во время установления соединения (используя Diffie-Hellman 2048 бит). Установление соединения между двумя router реализовано в классе EstablishState и подробно описано ниже. IV для шифрования AES/256/CBC — это последние 16 байт предыдущего зашифрованного сообщения.

Требуется 0-15 байт заполнения, чтобы общая длина сообщения (включая шесть байт размера и контрольной суммы) была кратна 16. Максимальный размер сообщения в настоящее время составляет 16 КБ. Поэтому максимальный размер данных в настоящее время составляет 16 КБ - 6, или 16378 байт. Минимальный размер данных равен 1.

Формат сообщения синхронизации времени

Особый случай — это сообщение метаданных, где sizeof(data) равен 0. В этом случае незашифрованное сообщение кодируется как:

+-------+-------+-------+-------+-------+-------+-------+-------+
|       0       |      timestamp in seconds     | uninterpreted
+-------+-------+-------+-------+-------+-------+-------+-------+
        uninterpreted           | Adler checksum of bytes 0-11  |
+-------+-------+-------+-------+-------+-------+-------+-------+

Общая длина: 16 байт. Сообщение синхронизации времени отправляется примерно каждые 15 минут. Сообщение зашифровано так же, как и стандартные сообщения.

Контрольные суммы

Стандартные сообщения и сообщения синхронизации времени используют контрольную сумму Adler-32, как определено в спецификации ZLIB .

Тайм-аут бездействия

Время ожидания простоя и закрытие соединения остается на усмотрение каждой конечной точки и может варьироваться. Текущая реализация уменьшает время ожидания по мере приближения количества соединений к настроенному максимуму и увеличивает время ожидания при низком количестве соединений. Рекомендуемое минимальное время ожидания составляет две минуты или более, а рекомендуемое максимальное время ожидания — десять минут или более.

Обмен RouterInfo

После установления соединения, а затем каждые 30-60 минут, два router должны обмениваться RouterInfo с помощью DatabaseStoreMessage. Однако Алиса должна проверить, не является ли первое сообщение в очереди DatabaseStoreMessage, чтобы не отправлять дублирующее сообщение; это часто случается при подключении к floodfill router.

Последовательность установления соединения

В состоянии установки соединения происходит 4-фазная последовательность сообщений для обмена DH ключами и подписями. В первых двух сообщениях выполняется 2048-битный обмен по алгоритму Диффи-Хеллмана. Затем обмениваются подписи критических данных для подтверждения соединения.

Alice                   contacts                      Bob
=========================================================
 X+(H(X) xor Bob.identHash)----------------------------->
 <----------------------------------------Y+E(H(X+Y)+tsB+padding, sk, Y[239:255])
 E(sz+Alice.identity+tsA+padding+S(X+Y+Bob.identHash+tsA+tsB), sk, hX_xor_Bob.identHash[16:31])--->
 <----------------------E(S(X+Y+Alice.identHash+tsA+tsB)+padding, sk, prev)
  Legend:
    X, Y: 256 byte DH public keys
    H(): 32 byte SHA256 Hash
    E(data, session key, IV): AES256 Encrypt
    S(): Signature
    tsA, tsB: timestamps (4 bytes, seconds since epoch)
    sk: 32 byte Session key
    sz: 2 byte size of Alice identity to follow

Обмен ключами DH

Первоначальный обмен ключами DH с использованием 2048-битных ключей использует те же общие простое число (p) и генератор (g), что и для шифрования ElGamal в I2P.

Обмен ключами DH состоит из нескольких шагов, показанных ниже. Соответствие между этими шагами и сообщениями, отправляемыми между I2P router’ами, выделено жирным шрифтом.

  1. Алиса генерирует секретное целое число x. Затем она вычисляет X = g^x mod p.
  2. Алиса отправляет X Бобу (Сообщение 1).
  3. Боб генерирует секретное целое число y. Затем он вычисляет Y = g^y mod p.
  4. Боб отправляет Y Алисе. (Сообщение 2)
  5. Алиса теперь может вычислить sessionKey = Y^x mod p.
  6. Боб теперь может вычислить sessionKey = X^y mod p.
  7. Теперь и у Алисы, и у Боба есть общий ключ sessionKey = g^(x*y) mod p.

sessionKey затем используется для обмена идентификаторами в Сообщении 3 и Сообщении 4. Длина экспоненты (x и y) для DH обмена документирована на странице криптографии .

Подробности о ключе сессии

32-байтовый ключ сессии создается следующим образом:

  1. Возьмите обмененный DH ключ, представленный как массив байтов положительного BigInteger минимальной длины (дополнительный код, big-endian)
  2. Если самый значимый бит равен 1 (то есть array[0] & 0x80 != 0), добавьте байт 0x00 в начало, как в представлении Java BigInteger.toByteArray()
  3. Если этот массив байтов больше или равен 32 байтам, используйте первые (наиболее значимые) 32 байта
  4. Если этот массив байтов меньше 32 байтов, добавьте байты 0x00 в конец для расширения до 32 байтов. (крайне маловероятно)

Сообщение 1 (Запрос сеанса)

Это DH запрос. Алиса уже имеет Router Identity , IP-адрес и порт Боба, которые содержатся в его Router Info , опубликованной в сетевой базе данных . Алиса отправляет Бобу:

 X+(H(X) xor Bob.identHash)----------------------------->

    Size: 288 bytes

Содержание:

 +----+----+----+----+----+----+----+----+
 |         X, as calculated from DH      |
 +                                       +
 |                                       |
 ~               .   .   .               ~
 |                                       |
 +----+----+----+----+----+----+----+----+
 |                                       |
 +                                       +
 |              HXxorHI                  |
 +                                       +
 |                                       |
 +                                       +
 |                                       |
 +----+----+----+----+----+----+----+----+

  X :: 256 byte X from Diffie Hellman

  HXxorHI :: SHA256 Hash(X) xored with SHA256 Hash(Bob's RouterIdentity)
             (32 bytes)

Примечания:

  • Боб проверяет HXxorHI используя свой собственный router hash. Если проверка не проходит, Алиса связалась не с тем router, и Боб разрывает соединение.

Сообщение 2 (Сессия создана)

Это DH ответ. Боб отправляет Алисе:

 <----------------------------------------Y+E(H(X+Y)+tsB+padding, sk, Y[239:255])

    Size: 304 bytes

Незашифрованное содержимое:

 +----+----+----+----+----+----+----+----+
 |         Y as calculated from DH       |
 +                                       +
 |                                       |
 ~               .   .   .               ~
 |                                       |
 +----+----+----+----+----+----+----+----+
 |                                       |
 +                                       +
 |              HXY                      |
 +                                       +
 |                                       |
 +                                       +
 |                                       |
 +----+----+----+----+----+----+----+----+
 |        tsB        |     padding       |
 +----+----+----+----+                   +
 |                                       |
 +----+----+----+----+----+----+----+----+

  Y :: 256 byte Y from Diffie Hellman

  HXY :: SHA256 Hash(X concatenated with Y)
         (32 bytes)

  tsB :: 4 byte timestamp (seconds since the epoch)

  padding :: 12 bytes random data

Зашифрованное содержимое:

 +----+----+----+----+----+----+----+----+
 |         Y as calculated from DH       |
 +                                       +
 |                                       |
 ~               .   .   .               ~
 |                                       |
 +----+----+----+----+----+----+----+----+
 |                                       |
 +                                       +
 |             encrypted data            |
 +                                       +
 |                                       |
 +                                       +
 |                                       |
 +                                       +
 |                                       |
 +                                       +
 |                                       |
 +----+----+----+----+----+----+----+----+

  Y: 256 byte Y from Diffie Hellman

  encrypted data: 48 bytes AES encrypted using the DH session key and
                  the last 16 bytes of Y as the IV

Примечания:

  • Алиса может разорвать соединение, если расхождение часов с Бобом слишком велико, как рассчитано с использованием tsB.

Сообщение 3 (Подтверждение сессии A)

Это содержит идентификатор router Алисы и подпись критических данных. Алиса отправляет Бобу:

 E(sz+Alice.identity+tsA+padding+S(X+Y+Bob.identHash+tsA+tsB), sk, hX_xor_Bob.identHash[16:31])--->

    Size: 448 bytes (typ. for 387 byte identity and DSA signature), see notes below

Незашифрованное содержимое:

 +----+----+----+----+----+----+----+----+
 |   sz    | Alice's Router Identity     |
 +----+----+                             +
 |                                       |
 ~               .   .   .               ~
 |                                       |
 +                        +----+----+----+
 |                        |     tsA
 +----+----+----+----+----+----+----+----+
      |             padding              |
 +----+                                  +
 |                                       |
 +----+----+----+----+----+----+----+----+
 |                                       |
 +                                       +
 |              signature                |
 +                                       +
 |                                       |
 +                                       +
 |                                       |
 +                                       +
 |                                       |
 +----+----+----+----+----+----+----+----+

  sz :: 2 byte size of Alice's router identity to follow (387+)

  ident :: Alice's 387+ byte RouterIdentity

  tsA :: 4 byte timestamp (seconds since the epoch)

  padding :: 0-15 bytes random data

  signature :: the Signature of the following concatenated data:
               X, Y, Bob's RouterIdentity, tsA, tsB.
               Alice signs it with the SigningPrivateKey associated with
               the SigningPublicKey in her RouterIdentity

Зашифрованное содержимое:

 +----+----+----+----+----+----+----+----+
 |                                       |
 +                                       +
 |             encrypted data            |
 ~               .   .   .               ~
 |                                       |
 +----+----+----+----+----+----+----+----+

  encrypted data: 448 bytes AES encrypted using the DH session key and
                  the last 16 bytes of HXxorHI (i.e., the last 16 bytes
                  of message #1) as the IV
                  448 is the typical length, but it could be longer, see below.

Примечания:

  • Боб проверяет подпись и при неудаче разрывает соединение.
  • Боб может разорвать соединение, если расхождение часов с Алисой слишком велико, как рассчитано с использованием tsA.
  • Алиса будет использовать последние 16 байт зашифрованного содержимого этого сообщения в качестве IV для следующего сообщения.
  • До выпуска 0.9.15 router identity всегда был 387 байт, подпись всегда была 40-байтовой DSA подписью, а padding всегда был 15 байт. Начиная с выпуска 0.9.16, router identity может быть длиннее 387 байт, а тип и длина подписи подразумеваются типом Signing Public Key в Router Identity Алисы. Padding выполняется по мере необходимости до кратного 16 байт для всего незашифрованного содержимого.
  • Общая длина сообщения не может быть определена без частичной расшифровки для чтения Router Identity. Поскольку минимальная длина Router Identity составляет 387 байт, а минимальная длина подписи составляет 40 (для DSA), минимальный общий размер сообщения составляет 2 + 387 + 4 + (длина подписи) + (padding до 16 байт), или 2 + 387 + 4 + 40 + 15 = 448 для DSA. Получатель мог бы прочитать это минимальное количество перед расшифровкой, чтобы определить фактическую длину Router Identity. Для небольших сертификатов в Router Identity это, вероятно, будет все сообщение, и больше не будет байт в сообщении, требующих дополнительной операции расшифровки.

Сообщение 4 (Подтверждение сессии B)

Это подпись критически важных данных. Боб отправляет Алисе:

 <----------------------E(S(X+Y+Alice.identHash+tsA+tsB)+padding, sk, prev)

    Size: 48 bytes (typ. for DSA signature), see notes below

Незашифрованное содержимое:

 +----+----+----+----+----+----+----+----+
 |                                       |
 +                                       +
 |              signature                |
 +                                       +
 |                                       |
 +                                       +
 |                                       |
 +                                       +
 |                                       |
 +----+----+----+----+----+----+----+----+
 |               padding                 |
 +----+----+----+----+----+----+----+----+

  signature :: the Signature of the following concatenated data:
               X, Y, Alice's RouterIdentity, tsA, tsB.
               Bob signs it with the SigningPrivateKey associated with
               the SigningPublicKey in his RouterIdentity

  padding :: 0-15 bytes random data

Зашифрованное содержимое:

 +----+----+----+----+----+----+----+----+
 |                                       |
 +                                       +
 |             encrypted data            |
 ~               .   .   .               ~
 |                                       |
 +----+----+----+----+----+----+----+----+

  encrypted data: Data AES encrypted using the DH session key and
                  the last 16 bytes of the encrypted contents of message #2 as the IV
                  48 bytes for a DSA signature, may vary for other signature types

Примечания:

  • Alice проверяет подпись, и при неудаче разрывает соединение.
  • Bob будет использовать последние 16 байт зашифрованного содержимого этого сообщения в качестве IV для следующего сообщения.
  • До релиза 0.9.15 подпись всегда была 40-байтной DSA подписью, а дополнение всегда составляло 8 байт. Начиная с релиза 0.9.16, тип и длина подписи определяются типом Signing Public Key в Router Identity Bob’а. Дополнение выполняется по мере необходимости до кратности 16 байтам для всего незашифрованного содержимого.

После установления

Соединение установлено, и могут обмениваться стандартные сообщения или сообщения синхронизации времени. Все последующие сообщения шифруются AES с использованием согласованного DH session key. Алиса будет использовать последние 16 байт зашифрованного содержимого сообщения #3 в качестве следующего IV. Боб будет использовать последние 16 байт зашифрованного содержимого сообщения #4 в качестве следующего IV.

Сообщение проверки соединения

Альтернативно, когда Боб получает соединение, это может быть проверочное соединение (возможно, инициированное тем, что Боб попросил кого-то проверить его слушателя). Check Connection в настоящее время не используется. Однако, для справки, проверочные соединения форматируются следующим образом. Информационное соединение проверки получит 256 байт, содержащих:

  • 32 байта неинтерпретируемых, игнорируемых данных
  • 1 байт размера
  • столько байтов, составляющих IP-адрес локального router (как он достигается удаленной стороной)
  • 2-байтовый номер порта, на котором был достигнут локальный router
  • 4-байтовое сетевое время i2p, известное удаленной стороне (секунды с начала эпохи)
  • неинтерпретируемые данные заполнения, до байта 223
  • xor хеша идентификатора локального router и SHA256 байтов с 32 по 223

Проверка соединения полностью отключена начиная с релиза 0.9.12.

Обсуждение

Теперь на странице обсуждения NTCP .

Дальнейшие работы

  • Максимальный размер сообщения должен быть увеличен примерно до 32 КБ.

  • Набор фиксированных размеров пакетов может быть уместен для дальнейшего сокрытия фрагментации данных от внешних противников, но дополнения на уровне tunnel, garlic и end-to-end должно быть достаточно для большинства потребностей до тех пор. Однако, в настоящее время нет provision для дополнения за пределами следующей 16-байтовой границы, чтобы создать ограниченное количество размеров сообщений.

  • Использование памяти (включая память ядра) для NTCP должно сравниваться с использованием памяти для SSU.

  • Могут ли сообщения установления соединения быть случайным образом дополнены данными, чтобы затруднить идентификацию I2P трафика на основе размеров начальных пакетов?

Was this page helpful?