По-настоящему важные данные нельзя держать в одном единственном месте — их нужно диверсифицировать.
Можно хранить всё дома и однажды вернуться с прогулки, а вместо дома и драгоценного компьютера — одни обугленные руины.
Можно носить всё с собой в телефоне, но лишиться его в первом же кафе, где аппарат вытащит у вас из кармана воришка.
Можно загрузить всё на надёжный сервер крупной корпорации, но в один прекрасный день эта корпорация введёт против вас санкции или просто заблокирует доступ к вашему же аккаунту.
У каждого отдельного хранилища есть свой собственный способ вас подвести.

Вот ровно эту проблему я и попытался решить.

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

Разберём шаг за шагом, как оно устроено под капотом.

Note
Note

Не одна программа, а две

Существует эта программа сразу в двух обличьях.
Десктопная версия написана на Python (PySide6/Qt) и работает на Windows и Linux.
Мобильная — на Flutter и Kotlin для устройств под Android.

И, забегая вперёд: это не одна программа, наспех портированная на телефон, а две совершенно независимые реализации одного решения, которые обязаны понимать друг друга бит в бит. Формат зашифрованного файла, кодировка операций синхронизации, правила разрешения конфликтов — всё это на двух языках написано отдельно и должно совпадать до последнего байта. Чтобы они не разошлись молча, есть отдельный набор кросс-языковых conformance-тестов: одни и те же входные данные прогоняются и через Python, и через Dart, а результат сверяется.

Интерфейс: если вы открывали Telegram, объяснять нечего

Слева узкая колонка папок, справа широкая лента, а внизу поле ввода. Заметки здесь ведут себя ровно как сообщения в чате: это может быть простой текст, форматированный текст, картинка, файл, целый альбом вложений или видео.

Интерфейс
Интерфейс

Ментальная модель предельно простая: папка — это чат, а заметка — сообщение в нём.

Поле ввода тоже знакомое: вложения откладываются в лоток, как в мессенджере, а отправленную заметку можно тут же поправить прямо на месте, без всяких отдельных окон. Форматирование, вставка картинок из буфера, drag-n-drop файлов в окно — всё как ожидаешь.

Для планирования есть календарь с цветными событиями, по которому удобно раскидывать дела по датам, — а сами события можно перетаскивать мышью с одного дня на другой.

Календарь
Календарь

Самое интересное прячется не в окне, а на диске

В основе всей программы лежит один принцип: источником истины являются файлы. Каждая ваша заметка — это обычный JSON-файл, который лежит в предсказуемой структуре каталогов:

<хранилище>/
  folders/<id-папки>/
    folder.json
    notes/<id-заметки>.json
    notes/attachments/<id-заметки>/
  calendar/events.json

Папка — это каталог, вложения лежат рядом, события календаря собраны в один файл. Перенести всё на другую машину означает буквально скопировать одну папку. А для удобства можно просто нажать кнопку экспорта в zip-архив.

Просто нажать кнопку экспорта в zip-архив
Просто нажать кнопку экспорта в zip-архив

Из такого подхода бесплатно вытекает важное свойство: поисковый индекс программа строит сама для себя, и по сути это всего лишь кэш, выводимый из файлов. Потеряли, повредили, удалили индекс — не беда, он перестроится из файлов-первоисточников.

Сам поиск при этом устойчив к опечаткам: под капотом работает не чёткое сравнение строк, а нечёткое совпадение по буквам (SQLite FTS5 для быстрого отбора кандидатов плюс rapidfuzz для ранжирования). А ещё он понимает даты: стоит ввести запрос с датой — и в выдачу первым делом попадут все заметки, привязанные к этому дню или просто созданные в этот день.

А ещё он понимает даты
А ещё он понимает даты

Синхронизация без сервера, облака и единого аккаунта

Но самая магия начинается там, где в дело вступает синхронизация. Здесь работает собственный peer-to-peer движок поверх вашей локальной сети.

Устройства находят друг друга через mDNS в общей сети Wi-Fi, а первичное доверие устанавливается сканированием QR-кода с одноразовым токеном, у которого есть короткий срок жизни.
Дальше всё общение идёт через взаимный TLS, причём доверие строится не через какие-то центры сертификации, а через закрепление сертификата (certificate pinning) — ровно так же, как это сделано в Syncthing.

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

Сопряжение: десктоп и телефон видят друг друга
Сопряжение: десктоп и телефон видят друг друга

А вот как именно сходятся данные — это отдельная инженерная история.

Параллельно с файлами программа ведёт журнал операций (op-log). Каждая ваша правка пишет не только сам файл для интерфейса, но и запись в этот журнал. Когда два устройства встречаются, они обмениваются так называемыми версионными векторами — кратким описанием того, кто что уже знает о заметках, — и докачивают друг у друга недостающие операции:

Устройство A:  vv = { A: 42, B: 17 }   // «я видел 42 своих операции и 17 от B»
Устройство B:  vv = { A: 40, B: 19 }
                     ↓  сверяем векторы
A → B: свои операции №41 и №42
B → A: операции B №18 и №19

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

Шифрование: пять цифр, которые нельзя перебрать

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

По умолчанию оно выключено, и пока вы его не включили, программа ведёт себя как самое обычное хранилище. Но стоит его активировать, как все данные на диске зашифровываются по алгоритму AES-256, причём у каждого файла свой собственный подключ, а путь к файлу намертво вшит в проверку подлинности (AAD). Это значит, что если злоумышленник просто перетащит зашифрованный кусок в другое место, расшифровка не пройдёт — и подмена сразу вскроется.

Самое интересное — это защита от перебора. ПИН-код здесь всего из пяти цифр.

Казалось бы, это 100 000 комбинаций, которые перебираются за считанные секунды. Но хитрость в том, что ПИН тут не используется как пароль напрямую. Он подаётся на вход аппаратному модулю, который вычисляет криптографический код на неизвлекаемом ключе. На десктопе эту роль играет TPM, а на телефоне — Android Keystore.

Если очень упростить, это отдельный специализированный криптографический чип на материнской плате устройства. Без этого конкретного железа значение попросту невозможно вычислить — а значит, украденные файлы превращаются в бесполезный мусор. Перебор нельзя даже начать, потому что у вора нет того самого чипа.

экран ввода ПИН из пяти цифр
экран ввода ПИН из пяти цифр

Поверх этого, на всякий случай, накручен ещё и медленный, требовательный к памяти алгоритм (scrypt), чтобы любая попытка угадывать стоила дорого.
А после нескольких неверных попыток включается нарастающая блокировка: сначала минута, потом 5 минут, потом полчаса, 2 часа и в итоге целые сутки.
Если же кто-то ввёл неправильный ПИН больше пяти раз подряд — данные стираются безвозвратно. И сам счётчик неудач защищён от обнуления: его не сбросить ни удалением файла, ни переводом системных часов назад.

А если у злоумышленника root?

Но что, если злоумышленник не просто унесёт ваши файлы, а получит root прямо на самом устройстве? С таким доступом он может прочитать любой файл приложения и даже обратиться к защищённому хранилищу ключей. Чего он сделать не в состоянии — это попасть в ту самую изолированную зону железа, где чип сверяет ваш отпечаток пальца или лицо и выносит вердикт, что аутентификация пройдена. Это решение принимается только внутри отдельной защищённой среды, а не в ядре системы, которым владеет root.

И вот ровно на этом держится дополнительная защита с биометрией. Если её включить, то проверка ПИН переезжает на особый ключ, которым чип соглашается воспользоваться только после свежей, подтверждённой железом биометрии. А поскольку главный ключ всего хранилища выводится именно через этот шлюз, то даже тот, кто знает ваш ПИН и обнулил счётчик попыток, не сможет развернуть его без вашего живого присутствия.

Однако важно оговориться, что это не панацея. Биометрия защищает данные, пока устройство заперто и вас нет рядом. Но если root уже пробрался в систему, у злоумышленника есть удалённый доступ, а вы сами сидите в открытом приложении — он по-прежнему способен вытащить ключ прямо из оперативной памяти. Поэтому элементарную цифровую гигиену вам по-прежнему нужно соблюдать. Я специально не пытаюсь продать вам «абсолютную защиту» — её не существует.

Режим «под принуждением»

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

Вам достаточно ввести свой ПИН задом наперёд.

Снаружи это выглядит как абсолютно обычная разблокировка: никаких предупреждений, никаких ошибок, ничего подозрительного. Но в этот самый момент программа необратимо уничтожает все ваши настоящие данные и открывает вместо них правдоподобную подложку — свежую папку с парой случайных заметок, которая на каждом устройстве выглядит немного по-своему, чтобы её нельзя было опознать как заготовку.

после обратного ПИН вместо настоящих данных показывается правдоподобная подложка
после обратного ПИН вместо настоящих данных показывается правдоподобная подложка

Уничтожение при этом начинается с криптографического стирания. Программа в первую очередь удаляет ту самую обёртку, которой зашифрован главный ключ. После этого весь реальный шифротекст превращается в нечитаемый мусор — и даже этот мусор тоже затирается. При этом ваши другие данные, даже если они лежат в одной папке с шифротекстом, не пострадают: стирание идёт строго по явному списку того, чем владеет само приложение, и никогда не трогает соседние файлы.

Как это проверялось: «рой» тестировщиков и сетка регрессий

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

И вот здесь — про ИИ честно и без прикрас: код обеих версий я писал в паре с ИИ-агентом, а роль независимых тестировщиков безопасности играл целый рой ИИ-агентов, каждый из которых пытался сломать систему со своей стороны.

Ключевой принцип: каждое найденное слабое место закрывалось не просто заплаткой, а отдельным тестом, который следит, чтобы проблема больше не вернулась. Потеря данных при внезапном отключении питания, утечка шифротекста в интерфейс, попытки сбросить счётчик перебора, расхождение устройств при синхронизации, переполнение памяти по сети — всё это было поймано и закрыто, и на каждый случай теперь есть красный тест, который станет зелёным только когда баг действительно исправлен.

Отдельная гордость — та самая кросс-языковая сетка: набор сценариев вида «дан список конкурентных операций → вот каким обязано быть финальное состояние», который прогоняется и на Python, и на Dart, во всех возможных порядках доставки. Именно она гарантирует, что телефон и десктоп понимают правила синхронизации одинаково и не разойдутся на тонком краевом случае.

Честно про компромиссы

Ультимативная ли это система защиты? Конечно же нет.

Эта программа — компромисс между удобством и безопасностью. Очевидно, что ПИН-код вводить проще, чем трёхсотзначный пароль несколько раз под разные слои зашифрованного контейнера. А синхронизировать файлы автоматически через домашнюю сеть легче, чем передавать их по проводу или флешке. Поэтому я и не настаиваю на использовании подобного софта — это был ещё один эксперимент, в котором ИИ выступал писателем программ, а рой ИИ-агентов — независимыми тестировщиками безопасности.

Код открыт

Весь код обеих версий выложен в открытый доступ под лицензией GPL-3.0:

А целиком, со всеми демонстрациями вживую, приложение показано в видео:

Спасибо, что дочитали до конца.

Комментарии (2)


  1. cpud47
    20.07.2026 08:45

    Что будет, если после ввода пинкода наоборот выйти и ввести его ещё раз? Откроется ли то же самое? Если нет, то это не имеет смысла

    Edit: ну и в целом отличить пинкод и пинкод наоборот можно через скорость ввода (на отдельном устройстве)


  1. 413x
    20.07.2026 08:45

    Есть еще такой вариант P2P заметок - EasyNotes, с классическим дизайном для Windows, Android и iOS, центром выступает Windows приложение