Search
Write a publication
Pull to refresh

PQ Proxy на .Net

Level of difficultyMedium

Предисловие

От скуки я решил глубже разобраться в криптографии и посмотреть, какие изменения нас ожидают в ближайшем будущем. С первых же поисковых запросов стало ясно, что идёт активная стандартизация пост-квантового шифрования (далее — PQ). Так появилась идея реализовать собственный прокси-сервер с нативной поддержкой PQ-TLS.

Идея и проблематика

На рынке практически отсутствуют готовые прокси или шлюзы с «из коробки» поддержкой PQ. Некоторые решения предлагают отдельные модули, но они расположены не в main-ветках, а детальных инструкций по установке и настройке нет.


Поэтому я сформулировал типовую задачу:

«У меня есть back-end-сервис, работающий по TLS 1.2/1.3. Мне нужно подключиться к сервису, использующему PQ-TLS, но у меня нет времени и ресурсов мигрировать код. Требуется рабочее решение прямо сейчас».

Отсюда требования:

  1. Быстрое развёртывание.

  2. Поддержка всех доступных PQ-KEM.

  3. Производительность > 600 RPS на одно ядро.

Проблемы, с которыми я столкнулся

1. Сборка OpenSSL + OQS

Главная задача — собрать классический OpenSSL с OQS-provider. Готовая сборка с нужными библиотеками есть, но, к сожалению, проект заморожен, что в репозитории не указано.

В результате я собрал связку: OpenSSL 3.5.1 + liboqs 0.14.0 + oqs-provider 0.9.0 на Linux. Все попытки собрать под Windows пока безуспешны; возможно, нужно глубже изучить процесс.

2. Отсутствие ряда методов в OpenSSL 3.5.1

В собранной библиотеке отсутствовали вызовы SSL_SET1_GROUPS_LIST SSL_SET_MIN_PROTO_VERSION и SSL_SET_TLSEXT_HOSTNAME, хотя они описаны в официальной документации. Пришлось использовать:

SSL_CTX_ctrl(_ctx, SSL_CTRL_SET_GROUPS_LIST, 0, groupsPtr);
SSL_ctrl(_ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, hostPtr);
SSL_CTX_ctrl(_ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, TLS1_3_VERSION, NULL);

3. Генерация сертификатов «на лету»

Разрывы соединений из-за несоответствия сертификата домену оказались самой трудоёмкой частью. Позже выяснилось, что проблема типична для тех, кто недостаточно глубоко разобрался в TLS-рукопожатии и самом процессе установления соединения.

Проверка работоспособности

  1. TShark-анализ
    Сначала я прослушивал трафик и анализировал tls.handshake через tshark. Запуская curl к сервису Post-Quantum Key Agreement at Cloudflare

    проверял следующие поля:

    • Supported Group

    • Key Share Entry: Group

    В них должны появляться значения Unknown (0x11ec) или Unknown (4588). При использовании ML-KEM-768 (правильная форма, а не «MLKEM768») с вспомогательной группой дополнительно виден x25519 (0x001d). Наличие Unknown (4588) подтверждает PQ-рукопожатие. (подробней о ClientHello при использовании PQ)

  2. Тест через системный прокси
    Затем я назначил прокси системным в Windows и использовал Microsoft Edge (он берёт настройки OS, в отличие от DuckDuckGo, которым я обычно пользуюсь). Тест выявил ошибки чтения/записи байтов при ответе на рукопожатие (в Linux-версии curl их не было). После исправлений все режимы — both (ML-KEM + x25519), pqonly (ML-KEM-768) и classic (x25519) — прошли успешно.

    Итог

    Сейчас есть рабочий прокси с PQ-TLS, который можно задать как системный или указать сервису для вывода трафика, но пока что. производительность ниже цели ≈ 150 RPS и не реализован https:// обращение к pq proxy от back-end. Пока что продолжается оптимизация кода.

    Подробные инструкции по сборке и исходники доступны на GitHub / GitVerse

    Статьи и источники

Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.