К содержанию
ГаджетыРазбор · 4 мин чтения

SHIFROM: мессенджер с тремя маршрутами до сервера и Xray-core внутри Android-приложения

Разработчик мессенджера с открытым кодом SHIFROM рассказал, как приложение на Kotlin Multiplatform поддерживает связь с сервером через три маршрута: прямой WebSocket, Tor и Xray-core, встроенный в процесс через JNI-библиотеку. Пользователь выбирает режим приватности, а маршрут назначается автоматически.

Коротко

  • Мессенджер SHIFROM использует три маршрута до сервера: прямой WebSocket, Tor и Xray-core, встроенный в приложение через JNI-библиотеку.
  • Пользователь выбирает режим приватности, а маршрут назначается автоматически; при ошибке цепочка переключается на следующий, но без понижения приватности.
  • Проект находится в стадии Alpha 2, публичного релиза нет, код и таблица полевых тестов доступны на GitHub.

Разработчик под псевдонимом LiudvigVladislav создаёт мессенджер с открытым кодом и сквозным шифрованием под названием SHIFROM. Клиент написан на Kotlin Multiplatform, сообщения проходят через сервер-ретранслятор. Проект находится в стадии Alpha 2, публичного релиза нет; на GitHub лежит только историческая тестовая APK от Alpha 1. Протокольная композиция (X3DH, Double Ratchet и Sealed Sender поверх libsodium) не проходила независимый аудит. Первым идёт Android; версии для iOS и веба планируются, но сроки не названы.

Что произошло

У клиента один транспортный интерфейс и три способа дойти до ретранслятора: прямой WebSocket поверх TLS (самый быстрый и экономный по батарее), WebSocket через onion-сервис Tor (самый медленный, только для текста) и Xray (резервный маршрут для нестабильных сетей). Маршрут пользователь не выбирает — он выбирает режим приватности, а режим задаёт упорядоченную цепочку. В режиме Ghost, если Tor не поднялся, пользователь видит ошибку, а не тихо пониженный уровень приватности.

Xray-core написан на Go. Разработчик выбрал встраивание через JNI-библиотеку libgojni.so (весом около 45 МБ) вместо запуска отдельного процесса. Это даёт единый жизненный цикл с приложением, не требует следить за дочерним процессом и обходит ограничение Android 10 на запуск исполняемых файлов из домашнего каталога. Библиотека собирается под четыре ABI: arm64-v8a, armeabi-v7a, x86 и x86_64. Для iOS нужна отдельная сборка gomobile, которая работает только на macOS, — её пока нет.

Ядро поднимает SOCKS5-слушатель на 127.0.0.1. Порт теперь выбирает ОС, чтобы избежать конфликта с другими приложениями (первая версия использовала порт 10808, что вызывало ошибку bind: address already in use). После запуска проводится перекрёстная проверка: делается GET /health к ретранслятору через этот порт. Ответ 200 означает, что работает весь путь.

Менеджер маршрутов проходит цепочку текущего режима: запускает подсистему, ждёт Ready и порта SOCKS в пределах бюджета на запуск, проверяет /health, при успехе возвращает маршрут, при отказе гасит подсистему и переходит к следующему. Если цепочка кончилась, выбрасывается NoTransportReachableException со списком попыток. Бюджеты этапов разделены: для Xray 30 секунд на ожидание Ready, для Tor 90, для прямого 25. Внешний таймаут оставляет запас поверх внутреннего.

После успеха менеджер запоминает, какой маршрут сработал, но только если это был первый маршрут цепочки. Подсказка действует 24 часа. Если сработал резервный маршрут, он не становится основным — это предотвращает ловушку, когда после короткого сбоя сеть восстанавливается, но приложение продолжает использовать Tor.

Проход цепочки запускается при холодном старте приложения, перезапуске foreground-сервиса, смене режима и значимой смене сети (например, Wi-Fi сменился мобильной сетью). Между двумя проходами должно пройти не меньше 5 секунд, кроме случая, когда сеть вернулась после полного отсутствия. Если на устройстве включён системный VPN, маршрут Xray из цепочки убирается.

Для доставки сообщений, когда WebSocket работает, но фреймы теряются, предусмотрен REST поверх того же маршрута. Режимом управляет конечный автомат с тремя состояниями: WsActive (всё через WebSocket), RestActive (отправка и опрос через REST) и WsCandidate (сокет есть, но ещё не доказал работу). Автомат стартует в RestActive и переходит в WsActive только после подтверждения исходящего сообщения или входящего фрейма.

Почему это важно

Для разработчиков мобильных приложений, которым нужна надёжная связь с сервером в условиях нестабильных сетей, описанный подход предлагает готовую схему: встраивание Xray-core через JNI-библиотеку, автоматический выбор маршрута на основе режима приватности, раздельные бюджеты времени на запуск и проверку, а также механизм запоминания только первого успешного маршрута. Для обычных пользователей это означает, что мессенджер может работать даже при блокировках или сбоях сети, не требуя ручного переключения.

Важно, что проект находится на ранней стадии (Alpha 2), криптография не проходила независимый аудит, а полевые тесты проводил только сам разработчик на одном бюджетном Android-телефоне. В таблице тестов, например, для маршрута Xray есть только один прогон. Разработчик честно перечисляет недостатки: не записана версия Android, почти не измерялась задержка, ни один тест не воспроизведён независимым человеком.

Что дальше

В планах — повторные прогоны маршрута Xray, тесты на других телефонах и версиях Android (с записью версии), замеры задержки, сборка ядра под iOS. Даты не названы. Код, ADR и таблица полевых тестов доступны на GitHub, информация о проекте — на shifrom.com.

Источники

  1. habr.com/news
Отправить в Telegram

Материал подготовлен с помощью ИИ на основе открытых источников и может содержать неточности. Нашли ошибку — напишите на hello@tolk.media.