Система шифрования данных: результаты теста на устойчивость в Web3

У Web3-проектов есть привычка продавать безопасность одним коротким словом: «AES-256». Для пользователя это звучит почти как гарантия: данные зашифрованы, значит прочитать их никто не сможет.

Система шифрования данных: результаты теста на устойчивость в Web3

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

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

Я бы не пытался искать единый «тест на устойчивость» для Web3. Такого универсального экзамена, после которого проект получает статус абсолютно защищённого, нет. Зато есть понятный маршрут проверки: отдельно оценить криптографию, отдельно — ключи, отдельно — интеграцию с блокчейном и отдельно — пользовательский путь. Именно так и стоит читать заявления о криптографической стойкости.

Что на самом деле проверяет NIST — и чего не проверяет

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

AES определён стандартом FIPS 197. У него есть три распространённых длины ключа: 128, 192 и 256 бит. При этом все варианты работают с блоками данных по 128 бит. То есть цифра в названии — AES-128 или AES-256 — говорит о размере ключа, а не о том, что один алгоритм «шифрует более крупные куски данных», чем другой.

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

Этим занимается программа валидации криптографических алгоритмов NIST — CAVP. В её рамках применяются тестовые векторы: системе дают ключ, входной текст и параметры, а затем сравнивают результат с эталонным. Для AES предусмотрены, в частности:

1. Known Answer Test — проверка, что на фиксированном входе реализация возвращает заранее известный правильный результат.

2. Monte Carlo Test — многократное повторение операций, которое помогает обнаружить ошибки, не заметные на одном коротком примере.

3. Multi-block Message Test — работа с сообщениями из нескольких блоков, где часто всплывают проблемы буферизации, счётчиков и обработки границ данных.

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

Валидация AES доказывает корректность криптографического компонента, но не безопасность пользовательского сценария вокруг него.

Это ключевое различие, которое часто теряется в маркетинговых материалах. CAVP и автоматизированное тестирование через ACVTS проверяют алгоритм или отдельные компоненты в формате black box: подали вход, получили ответ, сверили. Они не анализируют фронтенд, не ищут утечки в логах, не изучают права доступа в контракте и не проверяют, как команда восстанавливает доступ к ключам после потери устройства.

Ожидание против реальности

Вопрос к продуктуЧто обычно отвечает командаЧто нужно выяснить при проверке
Используется ли надёжное шифрование?«Да, AES-256»Какая библиотека применяется, как она тестируется, какой режим выбран и как создаются ключи
Защищены ли данные в облаке или IPFS?«Файлы зашифрованы до загрузки»Есть ли шифрование на стороне клиента, кто получает ключ, остаются ли метаданные открытыми
Защищены ли транзакции?«У нас приватный протокол»Что скрывается фактически: сумма, адрес, содержимое, связь между действиями или только часть данных
Безопасен ли контракт?«Криптография проверена»Кто может вызвать функции, как валидируются входные данные, есть ли риск повторного входа и опасных внешних вызовов
Готов ли проект к будущим угрозам?«Мы следим за постквантовой криптографией»Есть ли карта миграции, инвентаризация ключей и понимание, какие зависимости придётся менять

Сама по себе фраза «мы используем стандарт NIST» — нормальная стартовая точка. Но это не финальный вердикт. Если продукт не может внятно объяснить, где хранятся ключи, как устроена ротация и что произойдёт при компрометации одного аккаунта, разговор о стандартах остаётся слишком удобным и слишком неполным.

AES без аутентификации: когда расшифрование работает, а данные уже подменили

Вторая типичная ошибка — проверить только то, что текст успешно шифруется и расшифровывается. Для демо этого достаточно. Для защиты информации — нет.

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

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

Для таких задач часто используется GCM — режим, описанный в NIST SP 800-38D. Это аутентифицированное шифрование с ассоциированными данными, или AEAD. В человеческом переводе: система не только прячет содержание, но и прикладывает криптографическую пломбу. При расшифровании она обязана убедиться, что ни шифротекст, ни тег аутентичности, ни связанные открытые данные не были изменены.

Ассоциированные данные здесь особенно полезны для Web3. Это информация, которую не нужно скрывать, но нужно жёстко привязать к сообщению. Например:

  • идентификатор пользователя или организации;
  • версия формата зашифрованного объекта;
  • идентификатор сети и адрес контракта;
  • тип операции: «создание записи», «обновление доступа», «отзыв ключа»;
  • счётчик версии или уникальный идентификатор документа.

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

Как выглядит минимальный тест GCM

Я бы не ограничивался фразой «GCM подключён в библиотеке». В тестовом наборе должны быть как минимум четыре сценария:

1. Корректное шифрование и расшифрование. Исходные данные после полного цикла должны совпадать побайтно, а не просто «выглядеть похожими в интерфейсе».

2. Подмена шифротекста. Изменяем один байт зашифрованного сообщения. Система должна остановиться с ошибкой аутентификации, а не вернуть частично повреждённый объект.

3. Подмена тега аутентичности. Меняем тег. Ожидаемый результат — такой же жёсткий отказ без попытки использовать расшифрованные данные.

4. Подмена ассоциированных данных. Меняем, например, адрес контракта или версию объекта. Расшифрование тоже должно завершиться отказом.

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

Здесь и проходит водораздел между демонстрацией и продуктом. В демонстрации можно зашифровать строку «hello world». В продукте нужно пережить параллельные запросы, повторную отправку транзакции, восстановление сессии, обновление приложения и работу на нескольких устройствах.

Почему правильный AES не спасает слабый смарт-контракт

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

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

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

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

Проверять здесь нужно не только криптографию, а весь маршрут:

  • Может ли произвольный адрес вызвать функцию выдачи или отзыва доступа?
  • Меняется ли состояние контракта до внешнего вызова, а не после него?
  • Можно ли повторно применить старую подпись или старое разрешение?
  • Проверяется ли сеть, адрес контракта, срок действия и идентификатор операции в подписываемых данных?
  • Может ли обновление proxy-контракта незаметно сменить логику доступа?
  • Не принимает ли контракт произвольный «хеш ключа» или ссылку на объект без привязки к конкретному владельцу и состоянию?

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

Шифрование отвечает на вопрос «кто прочитает байты», а контракт — на вопрос «кто сможет поменять правила доступа». В реальном продукте нельзя выбрать только один из этих вопросов.

EIP-196 и доказательства: полезный инструмент, но не замена секретности

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

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

В Ethereum для задач верификации некоторых zkSNARK-доказательств есть предкомпилированные операции, описанные EIP-196. В документе определены операции сложения и скалярного умножения на кривой alt_bn128: ECADD по адресу 0x6 и ECMUL по адресу 0x7. Указанная стоимость — 500 gas и 40 000 gas соответственно. Смысл предкомпиляций прагматичный: вынести тяжёлую математику в специальный механизм исполнения, чтобы проверка доказательств укладывалась в ограничения сети.

Для продуктовой команды отсюда следует не «можно просто добавить приватность», а более приземлённый вывод: надо заранее считать стоимость и UX каждого действия. Если пользователь вынужден оплачивать дорогую проверку при каждом открытии доступа или обновлении записи, он начнёт искать обходной путь. А обходные пути в приватных системах обычно выглядят одинаково: экспорт ключа в заметки, пересылка его в мессенджере, отключение лишних подтверждений, один пароль на всё.

Безопасный UX не означает убрать все шаги. Он означает убрать бессмысленное трение и оставить пользователю понятные, обратимые действия там, где цена ошибки высока.

Ключи — самый недооценённый слой системы

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

Вариантов много. Ключ может генерироваться на устройстве и никогда не покидать его. Может шифроваться паролем пользователя и синхронизироваться с облаком. Может делиться между несколькими участниками. Может храниться в аппаратном кошельке или защищённой области телефона. Может восстанавливаться через социальное восстановление или через корпоративную процедуру.

У каждого подхода есть цена, и она не только техническая.

Модель работы с ключомЧто удобно пользователюГде появляется риск
Ключ только на устройствеМаксимальная локальность, минимум доверия к серверуПотеря устройства может стать потерей доступа навсегда
Зашифрованная резервная копияЛегче перейти на новый девайс и пережить поломкуСлабый пароль или утечка параметров резервной копии ослабляют схему
Аппаратный кошелёкКлюч сложнее извлечь вредоносному ПОПоддержка может быть неудобной, а резервная фраза остаётся критичной точкой
Мультиподпись или разделённое управлениеНет единой точки контроля у одного участникаОнбординг сложнее, а потеря кворума блокирует операции
Социальное восстановлениеПользователь не остаётся один на один с потерей ключаНужно доверять выбранным участникам и защищать процесс смены хранителей

Здесь нет универсального победителя. Для личного архива с действительно чувствительными данными разумнее терпеть больше трения ради локального контроля. Для команды, где доступ должен пережить уход сотрудника и замену устройств, нужен управляемый процесс восстановления и отзыва прав. Худший вариант — когда сервис обещает и абсолютную самостоятельность, и мгновенное восстановление, но не объясняет, за счёт какой архитектуры совмещает эти свойства.

Полезный признак зрелого продукта — интерфейс прямо показывает последствия. Не прячет предупреждение в документации, а говорит человеческим языком: «Этот ключ хранится только на вашем устройстве. Без резервной копии мы не сможем вернуть доступ». Или: «Копия зашифрована вашим паролем; если пароль слабый, защита резервной копии будет слабее».

Постквантовая миграция: не кнопка, а инвентаризация

13 августа 2024 года NIST утвердил первые три стандарта постквантовой криптографии: FIPS 203 для ML-KEM, FIPS 204 для ML-DSA и FIPS 205 для SLH-DSA. Для индустрии это важный переход от обсуждений к стандартизированным строительным блокам. Но в Web3 вокруг них уже успело появиться слишком много неточных обещаний.

ML-KEM нужен для установления общего секретного ключа по публичному каналу. Его задача — помочь сторонам договориться о секрете, а не напрямую шифровать пользовательские файлы. ML-DSA и SLH-DSA — алгоритмы цифровой подписи. Они подтверждают авторство и целостность подписанного сообщения.

Эти роли нельзя смешивать:

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

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

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

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

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

3. Предусмотрен ли гибридный режим. На переходном этапе системе может понадобиться сочетать привычные и новые механизмы, не ломая совместимость.

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

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

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

Как я бы выносил вердикт по системе шифрования

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

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

Слабый продукт узнаётся по другому набору признаков: «AES-256» без объяснения режима, туманная история с резервными копиями, ключи в браузерном хранилище без модели угроз, контракт с неочевидными ролями администратора, а разговор о постквантовой защите — без конкретного плана миграции.

Именно поэтому результаты теста на устойчивость в Web3 не должны звучать как «прошёл» или «не прошёл». Честный вывод выглядит иначе: алгоритм реализован корректно; подмена данных вызывает отказ; ключи имеют понятный жизненный цикл; доступ в контракте ограничен и протестирован; обновления не ломают модель доверия; будущая миграция хотя бы спроектирована.

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

Частые вопросы

Почему AES-256 не гарантирует полную безопасность данных?
AES-256 — это лишь алгоритм шифрования. Безопасность зависит от того, как создаются и хранятся ключи, как проверяется целостность данных и как устроена логика доступа в смарт-контрактах.
Что такое аутентифицированное шифрование и зачем оно нужно?
Это режим шифрования (например, GCM), который помимо скрытия содержания добавляет криптографическую пломбу. Она позволяет системе обнаружить подмену данных или тега аутентичности и предотвратить использование скомпрометированной информации.
Можно ли считать смарт-контракт безопасным, если в нем используется надежное шифрование?
Нет, так как контракт управляет правами доступа и бизнес-логикой. Ошибки в контроле доступа, логике вызовов или обновлении proxy-контрактов могут скомпрометировать систему даже при использовании сильной криптографии.
Являются ли доказательства с нулевым разглашением (zkSNARKs) заменой шифрованию?
Нет, это разные инструменты. Доказательства подтверждают истинность утверждений без раскрытия данных, но они не делают открытые файлы секретными и не заменяют управление ключами.
Как правильно хранить ключи в Web3-проекте?
Универсального способа нет, но зрелый продукт должен предлагать прозрачную модель: от локального хранения на устройстве до мультиподписи или социального восстановления, четко объясняя пользователю риски каждого подхода.