Разработчик менеджера паролей рассказал, как убрал экран «неверный пароль» и попытался сделать так, чтобы любой ввод открывал какое-то хранилище. Идея проста: со стороны нельзя понять, существует ли у пользователя ещё один набор записей или перед вами пустая приманка.

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

Что произошло

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

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

Как это сделано

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

Проблему усиливали папки history/<имя>/ и sync/<имя>.json. По их наличию и по датам изменения легко было понять, какое хранилище живое, а какое пустое. Другими словами, шифрование было, но метаданные выдавали всё остальное.

В новой версии разработчик сменил схему. Ключ получают из пароля через Argon2id, сам файл хранит 24 байта nonce и дальше — шифротекст XChaCha20-Poly1305. Снаружи нет ни заголовка, ни версии, ни магических байтов. Даже имя файла стало случайным набором hex-символов.

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

Но самое интересное началось не в криптографии, а в метаданных. Чтобы не выдать себя размером, хранилища прячут в корзины по 4 KiB, 8 KiB, 16 KiB и так далее. Чтобы не выдать себя временем, всем файлам после записи ставят одинаковые даты создания, изменения и доступа. Внутри папки лежат одинаковые по виду файлы со случайными именами — снаружи не ясно, где основное хранилище, а где приманка.

Похожий принцип используют и в других сценариях, где важна не только криптография, но и маскировка структуры. Например, в разборе подмены обновлений AOMEI Backupper видно, как опасно, когда атакующий получает доступ не к содержимому, а к механике распространения и метаданным.

Кого это затронуло и где остались риски

Для обычного пользователя схема звучит привлекательно: открываешь любой пароль, а программа показывает либо настоящие записи, либо безобидную приманку. Но у подхода есть границы.

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

Есть и организационные риски. Синхронизация показывает серверу количество слотов, даже если сами данные шифруются. А если атакующий знает, что программа умеет подменять пустое и настоящее хранилище, он просто не поверит первому паролю. Тут уже не поможет ни XChaCha20-Poly1305, ни аккуратный Rust-код.

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

Что делать читателю прямо сейчас

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

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

  • Проверьте, включено ли шифрование локального хранилища и резервных копий.
  • Убедитесь, что менеджер паролей не сохраняет открытые данные в временных папках.
  • Посмотрите, не выдаёт ли программа лишнее по именам файлов, датам и истории изменений.
  • Используйте уникальный пароль для самого хранилища и не повторяйте его в других сервисах.
  • Включите 2FA там, где это возможно, особенно для почты и облака.
  • Если храните важные данные на нескольких устройствах, проверьте, как работает синхронизация и резервные копии.
  • Для внешних сетей и рабочих устройств держите под рукой менеджер паролей, 2FA и отдельный слой защиты соединения.
Поделиться: