Как я сделал шифрование поверх MAX, когда приватность стала роскошью
Когда единственный работающий мессенджер — в «белом списке», а тебе нужно отправить что-то, что видеть должен только получатель. История о том, как я без Mac, с помощью ИИ и GitHub Actions собрал кроссплатформенное приложение для шифрования.
Предыстория: интернет работает, но не для тебя
Представьте ситуацию. Интернет вроде есть, но работают только приложения из «белого списка». MAX, может быть ещё пара сервисов. Telegram — через раз. VPN — лотерея. А вам нужно отправить коллеге договор, другу — фотографию, или просто написать сообщение, которое не хочется показывать всему миру.
Вы открываете MAX, набираете текст... и понимаете: а кто гарантирует, что это сообщение читаете только вы и получатель? Никто. Ни один мессенджер из «белого списка» не даёт вам end-to-end шифрование, которому можно доверять. Вы просто верите на слово.
Именно в такой момент и родилась идея Dark Message.
Идея: не заменить мессенджер, а надеть на него бронежилет
Я не стал делать «убийцу Telegram» или «замену MAX». Это бессмысленно — если приложение не в белом списке, оно просто не будет работать.
Вместо этого я сделал слой шифрования поверх любого мессенджера. Схема простая:
Вы пишете сообщение в Dark Message
Приложение шифрует его AES-256 (тот же стандарт, что используют банки и военные)
На выходе — набор символов, который вы копируете и отправляете через MAX, email, хоть голубиной почтой
Получатель вставляет эту кашу в своё приложение Dark Message, вводит пароль — и читает оригинал
Мессенджер становится просто транспортом. Он передаёт зашифрованный текст, не зная, что внутри. Как конверт, который почтальон не может вскрыть.
И самое главное — приложение работает полностью офлайн. Нет разрешений на интернет. Вообще. Данные никогда не покидают ваше устройство.
Что можно шифровать
Текст — сообщения, заметки, пароли. Результат — строка Base64, которую можно отправить в любой чат.
Фотографии — зашифровать фото перед отправкой. На выходе файл
.darkm, который без пароля — просто набор байтов.Документы — PDF, Word, Excel, ZIP, что угодно. Тоже превращается в
.darkm.
Честно про ИИ: Claude как напарник
Скажу прямо — я делал этот проект с помощью ИИ. Claude (Anthropic) был моим напарником на протяжении всей разработки. И я считаю, что скрывать это — глупо.
Вот как это выглядело на практике:
Архитектура — я описывал задачу, Claude предлагал структуру, я корректировал
Код — Claude писал основу, я тестировал на реальных устройствах и находил баги
Отладка — когда шифрование между Android и iOS не работало, мы вместе анализировали байты, сравнивали ключи деривации, писали тесты на Python
Публикация — Apple дважды отклонил приложение, и каждый раз мы разбирали причины и исправляли
ИИ не заменил разработчика — он заменил команду. Вместо бэкенд-разработчика, iOS-разработчика, Android-разработчика и тестировщика у меня был один помощник, который знает все платформы. Но финальные решения, тестирование на железе и понимание «ч��о нужно пользователю» — это по-прежнему человек.
Без Mac? Не проблема: GitHub Actions + CI/CD
У меня нет MacBook. Совсем. А для сборки iOS-приложения нужен Xcode, который работает только на macOS.
Решение: GitHub Actions. Я настроил CI/CD pipeline, который:
Берёт код из репозитория
Запускает виртуальную macOS на серверах GitHub
Генерирует проект через XcodeGen (чтобы не хранить тяжёлый .xcodeproj в репозитории)
Собирает, подписывает и загружает билд напрямую в App Store Connect
Весь процесс — от коммита до появления билда в TestFlight — полностью автоматический. Я пишу код на Windows, пушу в GitHub, и через 15 минут получаю готовый iOS-билд на своём iPhone через TestFlight.
Для Android всё проще — Gradle собирает APK/AAB прямо на моём компьютере.
Техническая кухня: AES-256-GCM + PBKDF2
Для тех, кому интересны детали:
AES-256-GCM — симметричное шифрование с аутентификацией. Если кто-то изменит хотя бы один бит в зашифрованном сообщении — расшифровка не пройдёт. Это защита и от чтения, и от подмены.
PBKDF2-HMAC-SHA512 — деривация ключа из пароля. 600 000 итераций. Даже если кто-то получит зашифрованное сообщение, перебор паролей будет стоить очень дорого.
Формат пакета:
[version:1B][contentType:1B][salt:16B][nonce:12B][ciphertext+GCM_tag:NB]— компактно и самодостаточно.
Каждое сообщение шифруется уникальным ключом (из-за случайной соли), даже если пароль один и тот же. Два одинаковых сообщения с одинаковым паролем дадут совершенно разный зашифрованный текст.
Кроссплатформенность: где я потерял неделю жизни
Самое весёлое началось, когда я решил сделать приложение и для Android, и для iOS, и для Windows.
Задача звучит просто: зашифровал на Android — расшифровал на iPhone. Что может пойти не так?
Оказалось — всё.
Проблема 1: Кириллица в паролях
Пользователь вводит пароль «привет» на Android, шифрует сообщение. Отправляет другу с iPhone. Друг вводит тот же пароль «привет» — и получает ошибку. При этом с паролем «hello» всё работает идеально.
Причина: Java (Android) и Swift (iOS) по-разному конвертируют кириллические символы в байты при деривации ключа. Java использует внутреннее представление через PBEKeySpec(char[]), а iOS — честный UTF-8 через Array(passphrase.utf8).
Решение: на Android я написал собственную реализацию PBKDF2, которая принимает пароль как UTF-8 байты напрямую, минуя стандартный Java API. Три дня отладки ради одной строчки passphrase.toByteArray(Charsets.UTF_8).
Проблема 2: Буква «а»
Во время тестирования я зашифровал слово «привет» с паролем «а» на Android, отправил на iPhone — не расшифровывается. Начал копать.
Написали на Python скрипт, который попробовал расшифровать сообщение разными вариантами пароля. Выяснилось: Android использовал латинскую «a» (код 0x61), а iPhone — кириллическую «а» (код 0xD0B0). Визуально — одинаковые символы. Технически — разные вселенные.
Это не баг приложения, а особенность клавиатур. Но такие вещи вылезают только при реальном тестировании на реальных устройствах.
Проблема 3: Argon2 vs PBKDF2
Изначально на Android я использовал Argon2id для деривации ключа — более современный и стойкий алгоритм. Но на iOS библиотека Argon2 ломала CI/CD pipeline на GitHub Actions (не могла скачать зависимости при сборке).
Пришлось перейти на PBKDF2 на обеих платформах. Менее модный, но надёжный, проверенный временем, и — главное — одинаково работающий везде.
Путь в магазины приложений: отдельное приключение
Apple App Store — три попытки
Apple отклонил приложение дважды, прежде чем одобрить.
Первый отказ: в описании я упомянул Telegram, WhatsApp и другие мессенджеры. Apple считает это «неточными метаданными» — нельзя упоминать сторонние платформы. Также скриншоты были сгенерированы, а не сделаны на реальном iPhone. И ссылка «Support URL» вела просто на профиль GitHub, а не на страницу поддержки.
Второй отказ: я обновил английское описание, но забыл русское. В русской локализации всё ещё красовались «MAX, Telegram, WhatsApp...». Apple проверяет ВСЕ локализации.
Третья попытка — прошла. Чистое описание, реальные скриншоты с iPhone, нормальная страница поддержки.
Уроки от Apple:
Никогда не упоминайте сторонние приложения в описании
Скриншоты — только реальные, с реального устройства
Проверяйте все языковые версии метаданных
Support URL — должна быть реальная страница с контактами
RuStore — соотношение сторон
RuStore отклонил из-за скриншотов — они требуют строго 9:16 для телефонов. Скриншоты с современных смартфонов (9:19.5) не подходят. Пришлось масштабировать с добавлением тёмного фона.
Также versionCode должен расти с каждой загрузкой — нельзя загрузить ту же или меньшую версию.
Результат: три платформы, полная совместимость
Зашифровал на телефоне — расшифровал на компьютере. Зашифровал на iPhone — расшифровал на Android. Любая комбинация работает.
Скачать
iOS (App Store):
Dark Message Crypto Chat в App Store
Android (RuStore):
Dark Message Crypto Chat в RuStore
Windows:
Десктопная версия доступна как .exe — напишите в комментариях, если нужна ссылка.
Как пользоваться
Установите приложение на своё устройство
Договоритесь с получателем о парольной фразе (лично, по звонку — не через тот же мессенджер!)
Напишите сообщение → нажмите «Зашифровать»
Скопируйте результат → отправьте через MAX, email, SMS — как угодно
Получатель вставляет текст в своё приложение → вводит пароль → читает
Для файлов — то же самое, только на выходе файл .darkm, который можно отправить как вложение.
Что дальше
Версия для Google Play (AAB уже собран, осталось опубликовать)
Возможно, open source — чтобы любой мог убедиться в отсутствии бэкдоров
Улучшение UX на основе отзывов
Вместо заключения
Я не призываю никого к паранойе. Но если существующие средства коммуникации не дают вам уверенности в приватности — теперь есть инструмент, который работает поверх любого из них.
Приложение не требует интернета, не собирает данных, не требует регистрации и шифрует стандартом AES-256. А сделано оно одним человеком с помощью ИИ, без единого Mac в радиусе ста километров.
Если у вас остались вопросы про реализацию, кроссплатформенную совместимость, работу с ИИ в разработке или процесс публикации в магазинах — добро пожаловать в комментарии.