Регистрация и аккаунт
Почему не нужны логин и пароль?
Во время регистрации приложение получает от сервера небольшую криптографическую задачу (Proof of Work) и решает её — это защита от автоматической регистрации ботами. Параллельно генерируются уникальные идентификаторы устройства и несколько наборов ключей шифрования: долгосрочные ключи идентичности, подписанные предварительные ключи и одноразовые предварительные ключи (включая постквантовые ML-KEM-1024). На сервер уходят только публичные части этих ключей и результат PoW-задачи. Приватные ключи никогда не покидают устройство. Пароля нет: аккаунт определяют ключи, а вернуть доступ к нему на новом устройстве можно ключом восстановления из 12 слов.
Можно ли выйти из аккаунта и войти заново?
Да, с ключом восстановления из 12 слов: на новом устройстве или после переустановки выберите «Восстановить» и введите слова. Вернётся аккаунт и его адрес; старые сообщения и сессии остаются на прежнем устройстве и не переносятся. Без этих слов потеря устройства или удаление приложения означает потерю аккаунта навсегда.
Как не потерять аккаунт при смене телефона?
Ключ восстановления создаётся сам при регистрации — ничего делать не нужно. Сохранить его копию (12 слов) можно позже, в Настройках: приложение напомнит, а до выхода из аккаунта попросит обязательно. Пока копия не сделана, слова хранятся на устройстве зашифрованными и открываются только после Face ID, отпечатка или кода телефона; после копии они с устройства стираются. Запишите их и храните в надёжном месте — у Konstruct нет вашего телефона и почты, это единственный способ вернуть аккаунт.
Контакты
Как написать кому-то?
Система устроена так, что незнакомый человек не может просто начать вам писать. Чтобы начать разговор, один делится QR-кодом или инвайт-ссылкой, а другой сканирует её или переходит по ней. Они одноразовые: QR-код живёт пять минут, ссылка — двенадцать часов, — принятую однажды ссылку использовать повторно нельзя. Отдельно вы можете включить в настройках обнаружение и стать находимым по имени пользователя; по умолчанию оно выключено, так что пока вы его не включили, инвайт — единственный путь.
Зачем такое ограничение? Это же неудобно.
Это намеренное решение. В большинстве мессенджеров достаточно знать номер телефона или никнейм, чтобы начать засыпать человека сообщениями. Здесь взаимное согласие зашито в архитектуру, а не просто задекларировано в политике.
Что будет, если кто-то поделится моим QR-кодом без моего ведома?
Код принимается только один раз, поэтому по разошедшейся ссылке сможет добавиться не больше одного человека, а уже использованная ссылка не сделает ничего. Кроме того, ссылка перестаёт действовать через двенадцать часов после создания, а QR-код — через пять минут. Если кто-то всё же добавился, вы увидите новый разговор и сможете сразу его заблокировать.
Шифрование и приватность
Как работает шифрование?
Все сообщения шифруются на устройстве отправителя перед отправкой и расшифровываются только на устройстве получателя. Сервер видит лишь зашифрованный поток и маршрутизирует его — прочитать содержимое он не может. Для установки сессии используется X3DH, расширенный постквантовым согласованием ключей (PQXDH): отправитель инкапсулирует секрет ML-KEM-1024 в Kyber-предключ получателя, и этот секрет входит в исходный ключ сессии вместе с классическими — именно это ограничивает сценарий «записать сейчас, расшифровать квантовым компьютером потом». Постквантовая защита действует с первого сообщения, а сессию без неё приложение не установит. Дальше работает Double Ratchet, меняющий ключи с каждым сообщением, — и у каждого сообщения есть ещё и свой постквантовый ключ, — так что компрометация одного ключа не раскрывает ни прошлых, ни будущих сообщений. Кто отправил сообщение, тоже скрыто постквантово; звонки защищены постквантовым DTLS, когда его поддерживают оба приложения. Пока классические: подписи сервера (сертификаты отправителя, журнал прозрачности ключей), вход устройства и восстановление аккаунта, токены Privacy Pass и транспортный TLS; групп пока нет; полный список — в спецификации протокола.
Что именно видит сервер?
Очень мало, и ничто из этого — вы. Чтобы доставить сообщение, серверу нужны непрозрачный идентификатор аккаунта получателя, размер шифротекста и время получения; ещё он хранит ваши публичные ключи и, на iOS, push-токен. Это весь список. Он не видит ни содержимого, ни вашего имени, ни аватара, ни списка контактов — и, на постоянно включённом пути защиты отправителя, не видит, кто отправил сообщение. Сообщения лежат у сервера только зашифрованными и удаляются по сроку хранения (около 7 дней), а не в момент доставки. Имя пользователя необязательно, в маршрутизации не участвует и хранится только ключевым хешем ради одной задачи — чтобы вас могли найти; сам поиск выключен, пока вы не включите обнаружение, так что по умолчанию аккаунт нельзя найти по имени вообще.
А метаданные? Кто с кем общается?
Это более трудная часть. Сервер всё ещё видит, что кто-то доставил шифротекст устройству B (получатель, время, размер). При постоянно включённой защите отправителя он не узнаёт, кто именно написал, — см. следующий вопрос. Защита от блокировок частично скрывает сетевой путь. Полная анонимность на уровне маршрутизации (спрятаться и от получателя, и от корреляции по IP и таймингам) — задача другого порядка, и сегодня она не решена.
Знает ли сервер, кто отправил сообщение?
Нет — поле отправителя не кладётся в конверт, и это всегда включено для обычного трафика (сообщения, квитанции о доставке, установка звонка, обмен профилями). Переключателя, который можно забыть, нет. Ваше устройство запечатывает подписанный сертификат отправителя на ключ получателя: получатель может его открыть и проверить, кто написал, а сервер — нет. Несколько внутренних путей — поддержание соединения, синхронизация ваших собственных устройств, служебные сообщения сессии — по замыслу по-прежнему несут отправителя.
Стоит уточнить, что именно скрывается, потому что это не личность. Её у сервера никогда и не было: аккаунт здесь — это пара ключей и непрозрачный идентификатор, без номера телефона, почты и настоящего имени, так что сопоставлять с человеком изначально нечего. Защита отправителя убирает последнюю связь между двумя такими идентификаторами — кто кому написал. Сетевой уровень — отдельный разговор, он выше: время и IP остаются видимыми, и именно там работает наблюдатель с ресурсами.
Ограничения: Защита отправителя скрывает его личность от сервера, но не время, размер или IP — это видно на сетевом/транспортном уровне. Токены Privacy Pass могут идти вместе с sealed-отправкой для анти-спама; server-side enforcement ещё раскатывается — rate-control на токенах пока дорабатывается и не завершён.
Вы собираете аналитику или телеметрию?
Нет — вообще. Никакой аналитики, метрик использования, поведенческих событий, отправки крашей, рекламных идентификаторов. Не «собрано и обезличено» — не собрано вовсе. В приложении нет сторонних трекеров (ни Firebase, ни Crashlytics, ни Sentry, ни Amplitude, ни Segment); единственные внешние зависимости — транспорт/медиа и на iOS — локальная библиотека распознавания речи. Релизные сборки к тому же не пишут диагностических логов на диск и не дают экрана дебага или экспорта логов. Когда нам нужны логи для починки бага, их отправляете вы кнопкой «поделиться» в бета-сборке — никакой тихой отправки.
Профиль
Зачем нужен Display Name?
Ваше отображаемое имя и аватар живут на устройстве; они не часть публичного профиля, и найти их никто не может. Когда вы начинаете новый разговор, собеседник видит только сгенерированный псевдоним — детерминированный, для данного ID всегда один и тот же. Чтобы показать настоящее имя и фото, откройте профиль собеседника и включите «Поделиться моим профилем»: и то, и другое пойдёт по зашифрованному каналу. Одно исключение: при отправке запроса в контакты к нему прикладываются ваше имя пользователя и отображаемое имя, чтобы получатель понимал, кто просит. Сервер хранит этот снимок зашифрованным, но под собственным ключом — это не сквозное шифрование; аватар в снимок не входит никогда.
Почему сгенерированное имя, а не просто пустое?
Пустое имя неудобно: в списке чатов вы видели бы безликие строки и не могли бы отличить один контакт от другого. Сгенерированное имя стабильно — «Быстрый Сокол» всегда будет «Быстрым Соколом» для этого ID, на любом устройстве.
Если у пользователя задан username, я его вижу?
Да. Приоритет отображения: Display Name (если поделился) → username → сгенерированное имя. Если человек зарегистрировался с username @john, вы увидите именно его, а не «Мирный Кит».
Сообщения
Что означают статусы у сообщений?
- Отправляется шифруется на вашем устройстве
- Отправлено ушло с устройства, сервер его принял
- Доставлено устройство получателя расшифровало его и прислало подтверждение
- В очереди ещё не ушло — приложение продолжает попытки само; нажмите, если не хотите ждать
- Не отправлено отклонено по причине, которую повтор не исправит, поэтому само ничего не произойдёт; нажмите, чтобы попробовать снова
Статуса «прочитано» нет, и это сделано намеренно: отметка о прочтении сообщила бы отправителю, когда вы открыли приложение, — факт о вас, который сообщению не нужен. «Доставлено» — это зашифрованная квитанция от устройства получателя, а не сообщение сервера о том, что он что-то переслал.
Можно ли редактировать отправленные сообщения?
Да, редактирование поддерживается. После изменения у сообщения появляется пометка «изменено». Редактирование распространяется на устройство получателя через тот же механизм доставки, что и обычные сообщения.
Почему иногда не приходят уведомления, когда приложение закрыто?
На iOS уведомления приходят через Apple Push Notification Service (APNs): нужен стабильный интернет, и если телефон в авиарежиме, за VPN с агрессивной фильтрацией или Apple сочла пуш «низкоприоритетным», уведомление может задержаться или не прийти. На Android push-сервисов нет вообще: приложение держит собственное соединение, о чём говорит постоянное уведомление; агрессивная экономия батареи или заблокированная сеть могут задержать сообщения. Когда приложение снова откроется, сообщения подтянутся автоматически.
Защита от блокировок
Работает ли Konstruct там, где мессенджеры блокируют?
В приложении есть режим защиты от блокировок: он меняет то, как приложение выходит в сеть, когда прямое соединение блокируется. В настройках это один переключатель на три положения — выкл, автоматически, вкл, — и по умолчанию стоит «автоматически»: пока прямое соединение работает, используется оно, переключение происходит только после доказанного отказа. Настраивать нечего, адреса вводить не нужно, всё происходит в фоне. Реализация открыта, так что дизайн может изучить кто угодно.
Защита от блокировок всегда включена?
По умолчанию — автоматически: прямое соединение быстрее, поэтому пока оно работает, используется оно, а переключение происходит только при доказанном отказе. Можно также принудительно включить или выключить. Чего мы намеренно не публикуем — какие именно техники сейчас в строю и где они сейчас проходят или не проходят: публичная и актуальная сводка по этому вопросу — бесплатная обратная связь для тех, кто блокирует. По той же причине этого не показывает и само приложение.
Устойчивость сети и жизнеспособность
Что будет если серверы Конструкта отключатся?
Обмен сообщениями останавливается до его возвращения. Альфа работает на одном доверенном сервере, и второго пути сегодня нет — ни реле, ни соединений напрямую, ни другого узла, на который можно опереться. Всё зашифрованное остаётся зашифрованным, ничего не теряется — просто не движется. Дорожная карта существует ровно ради того, чтобы это перестало быть правдой, и ничего из неё пока не выпущено.
Базовый мессенджинг всегда будет бесплатным?
Да — безусловно. Отправка сообщений, получение сообщений, E2EE и все функции безопасности никогда не окажутся за платным барьером. Модель только на донатах исторически оказалась хрупкой для privacy-проектов, поэтому Конструкт планирует комбинацию: добровольные пожертвования, опциональные premium-функции (большие файлы, расширенная история, темы — никогда функции безопасности) и B2B-хостинг для организаций. Ядро всегда будет бесплатным.
На что живёт Konstruct? Можно задонатить?
Без рекламы, без перепродажи данных, без телеметрии — обратная сторона в том, что Konstruct живёт на добровольных донатах. Они идут напрямую на разработку и сервер. Если цените приватность — предпочтите Monero (XMR), в отличие от биткоина его цепочка не публична. Перед отправкой всегда сверяйте адрес с репозиторием проекта на случай подмены страницы.
- Monero (XMR) — рекомендуется:
496i5qvPzRtJPQjiPXnLvEGutjHFth4pWDQaJwbbMreyaTYg4qfbo48MXrTnYH32MHiAn5GcSEN1c48EYBvVkrx9Pi5BWvn - Bitcoin (BTC):
bc1q5cthgu6k9utg9hk2mx2xshdtsrhvu54ysmqhmm - Ko-fi — удобно, но не приватно: платёжный сервис знает, кто вы:
ko-fi.com/construct_msg
Что такое P2P-режим и когда он активируется?
Режим P2P запланирован, но пока не реализован — весь трафик сейчас идёт через центральный сервер. Целевой замысел: когда оба собеседника одновременно онлайн и подключены к серверу Konstruct, сервер даст им сигнал перейти на прямое P2P-соединение поверх QUIC. После установки сервер уходит с пути доставки — трафик идёт напрямую между устройствами. Если одна из сторон уходит в офлайн, доставка возвращается на сервер.
Безопасность и защита
Что если мне начнут массово писать незнакомые люди?
Для этого в приложении есть «Режим защиты». Когда он включён, уведомления и оповещения приходят только от людей, которые были у вас в контактах на момент его активации. Сообщения от новых отправителей всё равно сохраняются — они просто не будут вас тревожить. Режим полезен, если вы публичный человек и хотите временно закрыться от новых контактов.
А если один конкретный человек начнёт спамить сотнями сообщений?
Если от одного отправителя приходит подозрительно много сообщений за короткое время (больше ~10 за 30 секунд), клиент автоматически покажет предупреждение и заглушит уведомления от него. Вы сможете либо разрешить его, либо заблокировать. Важно: это защита на стороне получателя и работает независимо от того, каким клиентом пользуется отправитель.
Технические вопросы
Что такое «сессия» и почему она иногда «ломается»?
Сессия — это установленный зашифрованный канал между двумя устройствами. Она строится на одноразовых ключах, которые нельзя переиспользовать, и ключи вращаются с каждым сообщением. Если приложение долго не работало, устройство переустановили или собеседник удалил чат — входящее сообщение может оказаться нечитаемым. Тогда приложение получателя сообщает отправителю, на каком состоянии сессии было написано это сообщение; приложение отправителя открывает новое состояние и отправляет сообщение ещё раз. Пользователь, как правило, ничего не замечает — сообщение просто приходит.
Поддерживается ли несколько устройств?
Привязать второе устройство в публичных сборках пока нельзя. Нативный десктоп-клиент заморожен, в разработке — консольный (TUI). Поскольку идентичность привязана к ключам, а не к аккаунту на сервере, многоустройственность требует отдельного механизма привязки ключей — над этим работаем.
Какой транспорт у Конструкта для live-сообщений?
Live-сообщения идут по двунаправленному gRPC MessageStream — один долгоживущий поток для heartbeat’ов, входящих сообщений и receipt’ов, без request/response polling. На актуальных iOS-сборках боевой путь — QUIC (construct-transport); если QUIC режется или handshake не проходит, клиент автоматически падает на gRPC поверх HTTP/2 + TLS 1.3. Сквозное шифрование не зависит от транспорта: по проводу едет только sealed ciphertext.
Для тестировщиков
Что проверять в первую очередь?
- Регистрация и добавление контакта по QR-коду
- Отправка и получение сообщений (в обе стороны)
- Статусы доставки — доходит ли сообщение до «доставлено», и повторяют ли отправку «в очереди» и «не отправлено» по нажатию?
- Редактирование сообщений — видит ли получатель изменения?
- Уведомления при свёрнутом приложении
- Поведение на плохой связи (авиарежим → восстановление)
- Восстановление аккаунта по ключу восстановления после переустановки
- Копия ключа восстановления из Настроек
Как сообщить о баге?
В диагностических (внутренних) сборках путь такой: Настройки → Диагностика и логи → Поделиться логами. Публичные сборки логов не ведут и этот экран вообще не компилируют — если в вашей сборке такой строки нет, опишите сценарий, и мы выдадим вам диагностическую сборку. Чем точнее описание (что делали, что ожидали, что произошло), тем быстрее мы разберёмся. Для проблемы с сессией приложите логи с обоих устройств.
Почему в логах так много повторяющихся строк?
В отладочных сборках некоторые компоненты пишут в лог при каждом обновлении интерфейса — для разработки это нормально. Строки вида FRC updated: 69 message(s) in window — это обновление списка чатов, они не означают проблемы.