За 6 месяцев разработали мессенджер, по уровню безопасности не уступающий WhatsApp или Telegram
Мы участвовали в разработке защищенного мессенджера для крупнейшей вьетнамской компании VSmart.

VMessage работает на iOS и Android. Обеспечивает быструю и безопасную связь. Позволяет создавать индивидуальные и групповые чаты, обмениваться сообщениями любых форматов и совершать аудио-звонки.
Что мы сделали
1
Провели аналитику
2
Спроектировали интерфейсы
3
Разработали сервер для совершения звонков и передачи сообщений
4
Разработали нативные iOS и Android приложения
User Flow
Подготовили подробное описание всей логики переходов между основными необходимыми модулями, согласовали между нашими отделами (ux/ui, iOS, android, backend), утвердили с клиентом, зафиксировали.
Feature Map
Собрали карту фичей продукта. Каждый крупный раздел приложения это ветвь диаграммы, а дальше идут подробности: списки, состояния ячеек, кнопки, типы отображения контента, особенности появления ошибок или запросов и так далее.

После этого, на этой карте мы, вместе с клиентом, выделили MVP (минимально жизнеспособный продукт) — это то, что мы точно запускаем в первой версии мессенджера в самые короткие сроки. Оставшиеся функции мы приоритезировали: что мы хотим доработать в перых спринтах после запуска, а что откладываем в бэклог.
Стиль
Цвета бренда
Акценты, основное меню, кнопки, выделение разделов
Градиенты
Подсветка кнопок, разделов меню и второстепенных элементов
Типографика
Для iOS и Android мы использовали нативные шрифты
Брендированные цифры
Собственное начертание цифр для добавления индивидуальности приложениям
Все мессенджеры на рынке сейчас выглядят почти одинаково. В принципе, наш не стал исключением. Нам важнее сделать интерфейс понятным, удобным и привычным пользователю, чем уникальным и удивляющим.

Поэтому, мы перенесли основные привычные паттерны поведения из популярных мессенджеров, особенно внимательно посматривая на Facebook Messenger, у него самая большая аудитория во Вьетнаме.

А для уникальности, узнаваемости и стильности мы расширили палитру бренда (сделали её более подходящий для экранов, добавили насыщенности и градиентных переходов), покрасили основные элементы в яркий оранжевый цвет, встроили в приложение брендированные цифры, нарисовали сочные иконки.
Иконки
Welcome Screens
Технологии
iOS: Swift
Android: Kotlin
Backend: Python, PostgreSQL, Janus, RabbitMQ, Lamb — наше собственное Open Source RESTful ядро
Интересные приемы в разработке
Аудиконференции по схеме MCU
MCU (multipoint control unit) позволяет значительно сократить расход трафика пользователей по сравнению с FM (Full Mesh — все участники соединены между собой и отправляют и получают аудио попарно) и SFU (Single Forwarding Unit — участники отправляет свое аудио один раз на сервер и получают входящее аудио от всех других участников по отдельному каналу) и сделать его не зависящим от количества участников конференции.

Для схемы MCU на каждого абонента приходится всего 2 аудио-канала, исходящий и входящий, смиксованный из каналов других участников. Сервер совершает дополнительную работу по декодированию, миксованию и кодированию потоков, но трафик каждого участника постоянен и не зависит от размера конференции. Это позволяет создавать аудиоконференции с любым количеством контактов.

Наши исследования также показали, что, при использовании современных кодеков и количестве участников больше 8, нагрузка на сервер оказывается даже ниже, чем при использовании SFU.
FM
2(n-1) каналов каждому абоненту
4 Mb/мин каждому из 5 абонентов
9 Mb/мин каждому из 10 абонентов
SFU
n каналов каждому абоненту
2,5 Mb/мин каждому из 5 абонентов
5 Mb/мин каждому из 10 абонентов
MCU
2 канала каждому абоненту
1 Mb/мин каждому из 5 абонентов
1 Mb/мин каждому из 10 абонентов
Протокол Диффи — Хеллмана разорван во времени для генерации сессионного ключа с пользователем, находящимся offline
Мы хотели предоставить нашим пользователям максимальный уровень конфиденциальности переписки и решили, что нам необходимо иметь, так называемую, совершенную прямую безопасность (Perfect Forward Secrecy или PFS). PFS заключает в том, что долгосрочная ключевая информация, хранимая на устройствах пользователей, не используется для шифрования сообщений и документов. Вместо этого, между пользователями создается временный (эфемерный) ключ, который меняется с каждым новым сообщением, а долгосрочные ключи используются только для взаимной аутентификации.

Таким образом, утечка долгосрочных ключей может скомпрометировать переписку пользователей, которая состоится после факта утечки, но не позволит злоумышленнику расшифровать трафик, сформированный до утечки ключей.

Проблема совершенной прямой безопасности заключается в необходимости присутствия двух пользователей в момент начала коммуникации для согласования эфемерного ключа по процедуре Диффи — Хеллмана. Очевидно, что пользователи мобильных устройств могут быть иногда недоступны (поэтому, например, если вы пользуетесь секретными чатами Telegram, то, при создании такого чата, вы видите сообщение «Ждем, когда собеседник будет онлайн» — это связанно с тем, что приложению необходимо согласовать эфемерный ключ).

Для решения этой проблемы мы применили методику «разрыва» процедуры Диффи — Хеллмана во времени. Каждый пользователь публикует свои «частичные» ключи (которые при стандартной процедуре он должен отправлять в ответ на запрос согласования) заранее на сервере (разумеется, снабжая их своей подписью и временем жизни), и, если мы хотим создать защищенную сессию с новым контактом, то мы забираем «частичный» ключ и считаем его «ответом» пользователя на наш запрос согласования, то есть можем сформировать полный ключ и начать отправлять сообщения и документы.

Получатель сессии, будучи онлайн, загрузит с сервера запрос на создание сессии и «доформирует» его до эфемерного ключа (суть протокола Диффи — Хеллмана в том, что этот эфемерный ключ будет таким же, какой получил инициатор сессии) и сможет расшифровывать входящие сообщения.
Полностью локальная история сообщений
Поскольку все сообщения зашифрованы и сервер не может их расшифровать (только отправитель и получатель имеют открытый текст каждого сообщения), вся история переписки хранится локально. Это создает множество технических задач по поддержанию консистентности, оптимизации запросов к такому локальному хранилищу. Но наши пользователи имеют доступ ко всей истории своей переписки без доступа к Интернету!
Long Poll для доставки асинхронных уведомлений по принципу Weak Updates
В ходе использования приложения, возникает огромное количество событий, о которых мы хотим уведомить пользователей моментально. Например, если другой пользователь начал печатать, сменил аватарку, поменял имя или прислал нам новое сообщение, а может, просто вышел онлайн.
Доставка таких уведомлений — серьезная нагрузка на сервер. Существует множество подходов и нами был выбран тот, который позволит обслуживать огромные пулы пользователей и горизонтально масштабироваться с ростом аудитории — так называемый Weak Messaging.

Если время сессии (продолжительность взаимодействия пользователя с приложением) невелико и составляет 10−20 минут в день, допустим подход с периодическим запросом изменений. В этом случае обновления доставляются «псевдоасинхронно», это создает достаточно большую паразитную нагрузку на сеть, батарею устройства и сервер.

В приложениях, где требуется «честная» асинхронная доставка обновлений используют два подхода: Strong Messaging и Weak Messaging. Разница заключается в том, что в Strong Messaging любое состояние приложения может быть обновлено до текущего актуального состояния. Этот подход значительно проще реализовать как на клиенте, так и на сервере, однако он имеет предел пользовательской базы, поскольку создает большую нагрузку на базу данных сервера.

Weak Messaging, напротив, позволяет обновить пользователя до актуального состояния только в определенном (небольшом) временном интервале, поэтому в нем различается синхронизация «холодного» старта, которая осуществляется запросом текущего состояния, и «горячая» синхронизация, осуществляемая отправкой обновлений. Этот подход обладает преимуществом String Messaging — асинхронную доставку атомарных обновлений — и не создает высокой нагрузки на диски / базу данных сервера, поскольку «слабые» обновления существуют только в оперативной памяти (этим и вызвано ограничение во времени на окно синхронизации). Если клиентское приложение по каким-либо причинам вышло за пределы окна синхронизации, оно будет вынуждено повторно провести «холодную» синхронизацию, чтобы вернуться к «горячим» обновлениям.
Тёмная тема
Добавили тёмную версию интерфейса. Глазам в тёмное время суток приятно и экономия заряда батареи телефонов с OLED-экранами.
В общей сложности приложение включает 15 основных модулей и 120+ нативных экранов на каждую платформу
Ещё проекты
NetNanny
Фармстандарт