Все записи

9 мин чтения

Почему ваши ключи никогда не покидают устройство

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

В CardanoWall ваши приватные ключи остаются на вашем устройстве. Программа, которая подписывает, запечатывает, выполняет пробное расшифровывание и проверяет записи, работает локально. Размещённый шлюз устроен так, чтобы никогда не получать ваш Identity Seed (сид идентичности), ваш ключ подписи, ваши ключи получателя и тот материал, который расшифровывает запечатанный файл.

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

О каких ключах идёт речь?

Идентичность Label 309 начинается с одного значения — 32-байтового Identity Seed. Из этого сида любая совместимая программа выводит ключи, которыми идентичность пользуется на практике, в трёх ролях:

  • ключ Ed25519, который подписывает записи;
  • ключ X25519, который получает классически запечатанные записи;
  • гибридный постквантовый ключ, который получает постквантово запечатанные записи.

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

Что клиент делает локально?

Клиент берёт на себя каждую операцию, которая касается приватного ключа:

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

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

А что тогда делает шлюз?

Шлюз ведёт конвейер публикации. Он может:

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

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

Почему это разделение важно?

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

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

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

В этом и состоит разница между сервисом, который говорит вам, что у него есть подтверждение, и подтверждением, которое стоит само по себе.

Может ли шлюз прочитать мои запечатанные файлы?

Если клиент запечатал содержимое правильно — нет: шлюз всегда видит только шифротекст.

Вот как устроена запечатанная запись. Публичная запись в блокчейне фиксирует хеш открытого текста — этот хеш вместе со временем блока и есть подтверждение момента. Сами зашифрованные данные в блокчейн не попадают; они лежат по контентно-адресуемому URI (например, ar://). Ключ содержимого упаковывается под один или несколько публичных ключей получателей — по одному слоту на получателя. Получатель (или отправитель) забирает шифротекст, расшифровывает его локально и пересчитывает хеш открытого текста, чтобы убедиться, что он совпадает с фиксацией в блокчейне.

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

Может ли шлюз подделать действительное подтверждение?

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

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

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

А что насчёт именно веб-приложения?

Веб-приложение — это программа, работающая в браузере, и это формирует его модель доверия.

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

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

А что насчёт десктопного приложения?

CardanoWall Desktop — это кросс-платформенное приложение с открытым исходным кодом, изначально построенное вокруг локального зашифрованного хранилища.

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

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

А что насчёт инструмента командной строки и SDK?

Они важны тем, что делают ту же модель доступной без сайта.

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

Инструмент командной строки и SDK имеют открытый исходный код и не привязаны к конкретному шлюзу, поэтому эту границу можно проверить, а не принимать на веру.

Что никогда нельзя отправлять на шлюз?

Никогда не отправляйте на шлюз — и ни на какой сайт — следующее:

  • ваш Identity Seed в формате L309-SEED-1…;
  • сырой сид в hex;
  • приватный ключ подписи;
  • приватный ключ получателя X25519;
  • гибридный постквантовый секрет получателя;
  • парольную фразу, которая расшифровывает запечатанное содержимое;
  • открытый текст, который вы хотели сохранить в тайне.

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

Что по-прежнему требует вашего внимания?

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

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

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

Почему это важно для открытого стандарта

Открытый стандарт подтверждений не должен зависеть от одного доверенного оператора.

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

Так что «ключи никогда не покидают устройство» — это не лозунг. Это часть того, что делает Proof of Existence переносимым: подтверждение, которое вы можете унести с собой за пределы любого отдельного сервиса, включая наш.

Коротко

Шлюз помогает опубликовать подтверждение. Клиент держит секреты.

Приватные ключи не отправляются на шлюз. Содержимое шифруется перед загрузкой. Расшифровка происходит локально. Верификация не требует верить сервису на слово. Это и есть та форма безопасности, на которой построен CardanoWall, — и та форма, которую Label 309 призван оставлять открытой.

Что почитать дальше

securityidentitycardanowall