Offline-раздача подписок

Раздавайте добавленную подписку другим устройствам без сервера: вся раздача упаковывается в самодостаточную ссылку или файл. Работает одинаково на Android и iOS.

ℹ️ Примечание Раздача полностью offline: конфиги не проходят через облачное хранилище и сторонние сервисы. Всё шифрование и все проверки выполняются на устройствах отправителя и получателя.


Обзор

Функция решает задачу «передать подписку другому человеку с ограничениями»:

ВозможностьОписание
Формат раздачиСсылка imsel://sub/..., QR-код или файл .imsel
СодержимоеСнапшот серверов (share-ссылки vless:///vmess:///... или Xray-JSON конфиги) либо URL подписки панели
ШифрованиеAES-256-GCM (зашифрованная раздача) или без шифрования (открытая)
ПривязкаПо HWID устройства, «первое устройство» или без привязки
ТаймерСрок с момента активации (1/3/7/30 дней) и/или абсолютный дедлайн
PINКод активации: без PIN ссылка криптостойко не расшифровывается
Ограничения получателяЗапрет активации на руте, блок настроек, скрытие конфигов, запрет повторной раздачи
Защита файлаПароль файла: AES-256-GCM + PBKDF2-HMAC-SHA256 (100 000 итераций)

Создание раздачи

Окно «Подписки» → карточка подписки → «Поделиться».

Что передать

  • Серверы (снапшот) — конфиги зашиты внутрь раздачи; получатель не видит URL панели и не может вынести конфиги в другой клиент по ссылке. Поддерживаются и share-ссылки, и JSON-конфиги (каждый парсится отдельно).
  • Ссылка — URL панели внутри раздачи; получатель сможет обновлять подписку напрямую с панели.

Защита

  • Шифрование AES-256 — полезная нагрузка шифруется AES-256-GCM; заголовок (привязка/таймер) защищён от подмены привязкой аутентификационных данных (AAD).
  • Привязка:
    • Без привязки — работает на любом устройстве;
    • 1-е устройство — закрепляется за первым активировавшим устройством;
    • По HWID — ключ раздачи обёрнут ключом, выведенным из HWID получателя функцией растяжения: на чужом устройстве раздача не расшифровывается вовсе. HWID получатель копирует кнопкой в боковом меню приложения.
  • PIN активации — при включении генерируется случайный PIN (можно перегенерировать кнопкой-спиннером; поле открыто — цифры нужно сообщить получателю). Ключ payload дополнительно оборачивается ключом, выведенным из PIN (PBKDF2 с растяжением — офлайн-перебор по ссылке вычислительно дорог). Работает только в зашифрованном режиме.

Срок действия

  • С активации — 1 / 3 / 7 / 30 дней с момента, когда получатель активировал раздачу (ссылка не «сгорает» до активации);
  • Дедлайн — абсолютная дата («до 31.12»).

Если заданы оба — действует то, что наступит раньше.

Ограничения получателя

ПараметрЭффект у получателя
Запрет на рутАктивация отклоняется на рутованных/jailbreak устройствах (эвристическая проверка)
Блок настроекНастройки подписки только для чтения; сетевой фильтр и блокировка не переключаются; авторская блокировка не снимается
Скрыть конфигиСкрываются кнопки QR и просмотра конфигурации на карточках серверов (остаётся только пинг), URL панели маскируется
Запрет re-shareВключён всегда: получатель не может передать подписку дальше (кнопка «Поделиться» неактивна)

Результат

После нажатия «Создать раздачу»:

  • QR-код — для раздач до ~2,5 КБ;
  • Ссылка — текст с копированием в буфер (для больших раздач показывается начало — копирование и файл используют полную ссылку);
  • В файл — сохранение через системный диалог проводника в файл .imsel; можно задать пароль файла.

Файл раздачи .imsel

Бинарный контейнер с бинарной магией-подписью формата и флагами. Внутри — ссылка раздачи:

  • Без пароля — контейнер без шифрования;
  • С паролем — содержимое шифруется AES-256-GCM, ключ выводится из пароля функцией растяжения (PBKDF2-HMAC-SHA256) со случайной солью. Подмена заголовка или содержимого ломает тег аутентификации — файл нельзя «пересобрать» незаметно.

Открытие файла

  • Android — тап по файлу в проводнике → «Открыть в IMSEL» (зарегистрированы intent-фильтры для расширения .imsel: content/file URI, октет-стрим);
  • iOS — тап в «Файлах» → открытие в IMSEL (зарегистрирован тип документа com.imsel.vpn.share);
  • Внутри приложения — меню «+» → «Импорт из файла».

Если файл защищён паролем — откроется диалог ввода пароля.


Активация у получателя

Входы: открытие ссылки imsel://sub/... (мессенджер/браузер), сканирование QR, вставка из буфера обмена, файл (см. выше).

Порядок:

  1. Диалог подтверждения «Активировать»;
  2. Если задан PIN — диалог ввода PIN (без верного PIN расшифровка невозможна);
  3. Проверки: срок, привязка (HWID/первое устройство), запрет рута;
  4. Создаётся локальная подписка (снапшот — с серверами внутри; ссылка — с последующим обновлением с панели) с ограничениями автора.

Результаты, которые может увидеть получатель: активирована / обновлена / срок истёк / закреплена за другим устройством / неверный HWID / неверный PIN / активация на руте запрещена / данные повреждены.

Ограничители после активации

  • Подключение к серверам истёкшей раздачи блокируется (включая «Переподключиться»);
  • Истёкшие раздачи пропускаются автообновлением;
  • Карточка подписки показывает бейдж: запас срока («7 дн.», «5 ч.») или красная «истекла».

Идемпотентность

Повторная активация той же ссылки на том же устройстве обновляет серверы, не создавая дубль и не продлевая срок. На другом устройстве ссылка с привязкой отклоняется.


Технические детали

Ссылки

ФорматНазначение
imsel://sub/e1/<base64url(envelope)>Зашифрованная раздача (AES-256-GCM)
imsel://sub/p1/<base64url(payload)>Открытая раздача (без шифрования)

Криптография (общее описание)

  • Полезная нагрузка шифруется AES-256-GCM со случайным 256-битным ключом; метаданные ограничений защищены от подмены привязкой аутентификационных данных (AAD).
  • Обёртки ключа (по HWID и по PIN) выводятся функциями растяжения ключа на основе PBKDF2-HMAC-SHA256 с рандомизированной солью; текущая версия формата (KDF v2) использует усиленные параметры, старые раздачи (KDF v1) остаются совместимыми.
  • PIN-обёртка делает офлайн-перебор PIN по ссылке вычислительно дорогим; тем не менее рекомендуется использовать длинные PIN и не передавать ссылку по открытым каналам.
  • Файл .imsel с паролем шифруется тем же стеком (AES-256-GCM + PBKDF2); подмена заголовка или содержимого ломает тег аутентификации.

Защита на устройстве получателя

  • Реестр активаций хранится в зашифрованном виде и подписывается ключом, привязанным к установке приложения, — подмена записей детектируется;
  • Предусмотрена защита от отката системных часов назад (перевод времени не продлевает срок раздачи).

ℹ️ Примечание Точные параметры ключевых функций, структура контейнеров и внутренние механизмы проверок в публичной документации не раскрываются (принцип Керкгоффса: стойкость не зависит от секретности формата, но и лишних подсказок публика не получает).

Честные ограничения offline-модели

  • Привязка по HWID и PIN криптостойки к передаче ссылки/файла другим лицам; однако владелец рутованного устройства-получателя может снять расшифрованные конфиги из памяти (без сервера это неотразимо);
  • Открытый формат p1 и режим «первое устройство» защищены только клиентскими проверками — патчированный клиент их обходит;
  • Ссылка в режимах без привязки — bearer-секрет: кто первым активировал, тот и владеет;
  • Отозвать offline-раздачу после отправки нельзя — только выпустить новую;
  • Clear Data у получателя неотличим от первого запуска.