Wormhole Messenger — минималистичный P2P-мессенджер на Rust с end-to-end шифрованием

История маскота: Хранитель туннелей
Во вселенной распределённых систем существует древний цифровой организм — Wormhole, или, как его называют в инженерных кругах, Хранитель туннелей.
Он не живёт в серверах, не привязан к IP-адресам и не сохраняет ничего в облаке. Его среда — шум пустоты между узлами. Он рождается каждый раз, когда два устройства обмениваются публичными ключами. Его тело состоит из энергии шифрования, а глаза — это криптографические nonce, всегда уникальные, всегда непредсказуемые.
Он не говорит. Он доставляет.
Каждое сообщение, проходя через его туннель, исчезает для всего мира — кроме одного получателя. Он не знает, что вы говорите, но знает, что это должно остаться между вами.
Когда вы запускаете Wormhole Messenger — вы не просто открываете чат. Вы пробуждаете существо, которое живёт между пингами, между кадрами WebSocket. Маскот — это визуальный облик этого криптографического духа, появляющегося каждый раз, когда вы выбираете приватность.
Введение
Rust уже давно зарекомендовал себя как язык для системного программирования, но также отлично подходит для реализации сетевых приложений, особенно в контексте безопасной и параллельной обработки. В этой статье я хочу представить Wormhole Messenger — простой, но функциональный P2P-мессенджер с end-to-end шифрованием, реализованный с использованием WebSocket, sodiumoxide и библиотеки axum.
Цели и архитектура
Основные цели:
Простая архитектура, легко расширяемая до desktop/web
Использование современных async-решений (
tokio
,axum
)Минимальная зависимость от сторонних серверов
Упор на приватность и безопасность
Архитектурная схема:
┌──────────┐ WebSocket ┌──────────┐
│ Client │ <-------------------> │ Server │
└──────────┘ └──────────┘
▲ ▲
│ │
│ E2E NaCl box │
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ wormhole_keys.json │ │ messages.json │
│ username.pk │ └──────────────────────┘
└──────────────────────┘
Реализация: серверная часть
Сервер реализован на axum
и tokio-tungstenite
. Его задача — только ретрансляция сообщений. Шифрование осуществляется исключительно на клиенте.
async fn handle_socket(socket: WebSocket, tx: Sender) { ... }
Каждое соединение обрабатывается независимо, с использованием канала передачи сообщений (broadcast::channel
). Сервер не хранит состояния и не расшифровывает данные.
Реализация: клиентская часть
Клиент при старте:
Загружает или генерирует пару ключей NaCl (
PublicKey
,SecretKey
)Подключается к WebSocket-серверу
Шифрует сообщения через
sodiumoxide::crypto::box_
Отправляет сериализованный пакет (
sender_pk:nonce:ciphertext:sender_name
)
let ciphertext = box_::seal(message.as_bytes(), &nonce, &recipient_pk, &sender_sk);
CLI-функциональность
Клиент поддерживает режимы:
client
— интерактивный чатencrypt
— шифрование сообщения вручную" " decrypt "
— расшифровка вручную" history
— просмотр локальной истории
Также реализована отправка уведомлений в Telegram при получении новых сообщений (опционально, через .env
).
Хранение ключей
Пара ключей сохраняется в wormhole_keys.json
. Публичный ключ также пишется в отдельный .pk
-файл (
) для облегчения использования в оффлайн-режиме:
let keys = StoredKeys {
public_key: base64::encode(pk.0),
secret_key: base64::encode(sk.0),
};
Преимущества и возможности расширения
Rust позволяет гарантировать безопасность памяти без сборщика мусора
Можно легко портировать на desktop (через Tauri) или web (через WebAssembly)
Расширение возможно за счёт подключения:
авторизации
мультиустройств
хранения метаданных (через sqlite или sled)
Исходный код: https://github.com/digkill/Wormhole
Заключение
Wormhole Messenger — это концепт, который демонстрирует, насколько просто можно реализовать безопасный мессенджер на Rust. С учётом минимализма кода и высокого уровня безопасности, он может послужить основой для более сложных решений в корпоративной или open-source среде.