[size=18]AnonPeer[/size]
Недавно решил попробовать написать собственный мессенджер на Rust. Основной целью было сделать федеративную систему обмена сообщениями, где пользователи могут общаться между разными серверами, а сами серверы не имеют доступа к содержимому переписки.
В итоге получился AnonPeer.
[size=16]Как работает федерация[/size]
Каждый сервер в сети является независимым узлом. Пользователь регистрируется на одном сервере и получает адрес в формате:
[code]username@domain[/code]
Например:
[code]
alP'nice ANUSserveBx^r-a PUNCTUMcktSom
bXIZob ANUSserver-PT|b PUNCTUMco&LUm
[/code]
Если Алиса отправляет сообщение Бобу, который находится на другом сервере, клиент сначала шифрует сообщение, после чего оно передаётся через сервер Алисы на сервер Боба.
Упрощённо это выглядит так:
[code]
Алиса
|
Сервер A
|
WebSocket
|
Сервер B
|
Боб
[/code]
При этом оба сервера видят только служебные данные и зашифрованный пакет.
[size=16]Структура проекта[/size]
Проект разделён на три части:
[list]
[]shared — общие структуры данных, криптография и сетевой протокол;
[]server — серверная часть на Axum;
[]client — десктопный клиент на Iced.
[/list]
Сервер использует PostgreSQL для хранения пользователей и публичных ключей.
Клиент хранит локальные данные в SQLite.
[size=16]Шифрование сообщений[/size]
Для обмена ключами используется X25519.
При регистрации клиент создаёт пару ключей:
[list]
[]приватный ключ;
[]публичный ключ.
[/list]
Публичный ключ отправляется на сервер, а приватный остаётся только на устройстве пользователя.
Когда начинается диалог, клиент получает публичный ключ собеседника и вычисляет общий секрет.
[code]
shared_secret = my_private_key × peer_public_key
[/code]
Из полученного секрета через HKDF выводится симметричный ключ.
Далее сообщение шифруется алгоритмом ChaCha20-Poly1305.
Каждое сообщение использует случайный nonce, поэтому одинаковые сообщения после шифрования будут иметь разный набор байтов.
Помимо шифрования используется Ed25519. Перед отправкой клиент подписывает сообщение своим ключом, а получатель проверяет подпись после получения.
Это позволяет обнаружить подмену сообщения или попытку отправить пакет от имени другого пользователя.
[size=16]Проверка на MITM</size]
Проблема классического обмена ключами заключается в том, что злоумышленник может попытаться подменить публичные ключи сторон.
Для проверки используется SAS (Short Authentication String).
После вычисления общего секрета обе стороны независимо получают короткий код:
[code]
a1b2-c3d4
[/code]
Если код совпадает у обоих пользователей, значит обмен ключами прошёл корректно.
Если значения отличаются, значит кто-то вмешался в соединение или произошла ошибка.
[size=16]Отправка сообщения[/size]
Процесс отправки выглядит следующим образом:
[list=1]
[]Получение публичного ключа получателя.
[]Вычисление общего секрета.
[]Генерация ключа через HKDF.
[]Шифрование ChaCha20-Poly1305.
[]Подпись Ed25519.
[]Отправка на сервер.
[/list]
Если получатель находится на другом сервере, сервер определяет домен из адреса и устанавливает соединение с удалённым узлом.
После доставки клиент получателя:
[list=1]
[]проверяет подпись;
[]расшифровывает сообщение;
[]сохраняет его в SQLite;
[]отображает в интерфейсе.
[/list]
[size=16]Технологии[/size]
Сервер:
[list]
[]Rust
[]Axum
[]Tokio
[]PostgreSQL
[]SQLx
[]DashMap
[]tracing
[/list]
Клиент:
[list]
[]Rust
[]Iced
[]SQLite
[]notify-rust
[*]rodio
[/list]
Криптография:
[list]
[]x25519-dalek
[]ed25519-dalek
[]chacha20poly1305
[]argon2
[]hkdf
[]sha2
[/list]
[size=16]Что получилось[/size]
Сейчас проект поддерживает регистрацию пользователей, обмен сообщениями между серверами, локальное хранение истории переписки, сквозное шифрование и проверку подлинности собеседника через SAS-коды.
Основная идея проекта заключалась не в создании очередного клона Telegram, а в попытке реализовать собственный федеративный протокол обмена сообщениями и разобраться на практике с криптографией, WebSocket-соединениями и распределённой архитектурой на Rust.
Недавно решил попробовать написать собственный мессенджер на Rust. Основной целью было сделать федеративную систему обмена сообщениями, где пользователи могут общаться между разными серверами, а сами серверы не имеют доступа к содержимому переписки.
В итоге получился AnonPeer.
[size=16]Как работает федерация[/size]
Каждый сервер в сети является независимым узлом. Пользователь регистрируется на одном сервере и получает адрес в формате:
[code]username@domain[/code]
Например:
[code]
[/code]
Если Алиса отправляет сообщение Бобу, который находится на другом сервере, клиент сначала шифрует сообщение, после чего оно передаётся через сервер Алисы на сервер Боба.
Упрощённо это выглядит так:
[code]
Алиса
|
Сервер A
|
WebSocket
|
Сервер B
|
Боб
[/code]
При этом оба сервера видят только служебные данные и зашифрованный пакет.
[size=16]Структура проекта[/size]
Проект разделён на три части:
[list]
[]shared — общие структуры данных, криптография и сетевой протокол;
[]server — серверная часть на Axum;
[]client — десктопный клиент на Iced.
[/list]
Сервер использует PostgreSQL для хранения пользователей и публичных ключей.
Клиент хранит локальные данные в SQLite.
[size=16]Шифрование сообщений[/size]
Для обмена ключами используется X25519.
При регистрации клиент создаёт пару ключей:
[list]
[]приватный ключ;
[]публичный ключ.
[/list]
Публичный ключ отправляется на сервер, а приватный остаётся только на устройстве пользователя.
Когда начинается диалог, клиент получает публичный ключ собеседника и вычисляет общий секрет.
[code]
shared_secret = my_private_key × peer_public_key
[/code]
Из полученного секрета через HKDF выводится симметричный ключ.
Далее сообщение шифруется алгоритмом ChaCha20-Poly1305.
Каждое сообщение использует случайный nonce, поэтому одинаковые сообщения после шифрования будут иметь разный набор байтов.
Помимо шифрования используется Ed25519. Перед отправкой клиент подписывает сообщение своим ключом, а получатель проверяет подпись после получения.
Это позволяет обнаружить подмену сообщения или попытку отправить пакет от имени другого пользователя.
[size=16]Проверка на MITM</size]
Проблема классического обмена ключами заключается в том, что злоумышленник может попытаться подменить публичные ключи сторон.
Для проверки используется SAS (Short Authentication String).
После вычисления общего секрета обе стороны независимо получают короткий код:
[code]
a1b2-c3d4
[/code]
Если код совпадает у обоих пользователей, значит обмен ключами прошёл корректно.
Если значения отличаются, значит кто-то вмешался в соединение или произошла ошибка.
[size=16]Отправка сообщения[/size]
Процесс отправки выглядит следующим образом:
[list=1]
[]Получение публичного ключа получателя.
[]Вычисление общего секрета.
[]Генерация ключа через HKDF.
[]Шифрование ChaCha20-Poly1305.
[]Подпись Ed25519.
[]Отправка на сервер.
[/list]
Если получатель находится на другом сервере, сервер определяет домен из адреса и устанавливает соединение с удалённым узлом.
После доставки клиент получателя:
[list=1]
[]проверяет подпись;
[]расшифровывает сообщение;
[]сохраняет его в SQLite;
[]отображает в интерфейсе.
[/list]
[size=16]Технологии[/size]
Сервер:
[list]
[]Rust
[]Axum
[]Tokio
[]PostgreSQL
[]SQLx
[]DashMap
[]tracing
[/list]
Клиент:
[list]
[]Rust
[]Iced
[]SQLite
[]notify-rust
[*]rodio
[/list]
Криптография:
[list]
[]x25519-dalek
[]ed25519-dalek
[]chacha20poly1305
[]argon2
[]hkdf
[]sha2
[/list]
[size=16]Что получилось[/size]
Сейчас проект поддерживает регистрацию пользователей, обмен сообщениями между серверами, локальное хранение истории переписки, сквозное шифрование и проверку подлинности собеседника через SAS-коды.
Основная идея проекта заключалась не в создании очередного клона Telegram, а в попытке реализовать собственный федеративный протокол обмена сообщениями и разобраться на практике с криптографией, WebSocket-соединениями и распределённой архитектурой на Rust.
Yggdrasil Network + Mimir.
Всё уже написано до тебя. Закрывай IDE и иди во двор на скамейку.
Всё уже написано до тебя. Закрывай IDE и иди во двор на скамейку.
>>038
а где здесь реклама? ни ссылки на гитхаб ничего нету
а где здесь реклама? ни ссылки на гитхаб ничего нету
Пиздатый мессенджер, жду бету
а где его протестировать на данный момент можно?
>нейронка высрала какую-то хуйню и я принес ее на харкач