Все записи

8 мин чтения

Где CardanoWall хранит ваши ключи в браузере

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

Когда вы разблокируете CardanoWall в браузере, разблокированный сид и выведенные из него приватные ключи живут в памяти сессии — обычной памяти приложения, которая исчезает, как только вы блокируете идентичность, выходите из аккаунта или закрываете вкладку. Постоянное браузерное хранилище (IndexedDB, sessionStorage) содержит только зашифрованный шифротекст хранилища и несекретные метаданные. Открытые Identity Seed и выведенные приватные ключи туда не записываются никогда.

Именно в этом различии весь смысл. Браузер обязан держать ключевой материал, чтобы подписывать и расшифровывать локально — иначе криптография попросту не работает. Вопрос безопасности никогда не звучит как «может ли браузер прикасаться к ключам?». Он вынужден. Вопрос в том, где эти ключи живут и что именно записывается на диск. Веб-модель CardanoWall построена так, чтобы перезагрузку переживал шифротекст, а не секреты.

Что нужно браузеру, пока идентичность разблокирована?

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

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

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

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

Что здесь такое память сессии?

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

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

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

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

Что записывается в IndexedDB?

Зашифрованный шифротекст хранилища — те же байты, что хранит сервер, а не сиды внутри них.

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

Атакующий, который лишь читает эту локальную базу данных, видит зашифрованные байты хранилища, адресованные вашим passkey, — а не открытые сиды. Кеш — всё ещё чувствительные служебные данные, и приложение стирает его при выходе из аккаунта, удалении аккаунта и изменении passkey. Но это не сама идентичность; это запертый ящик, ключи от которого лежат только внутри ваших аутентификаторов. (О том, как запечатывается этот ящик, читайте в материалах как CardanoWall хранит вашу идентичность и как passkey защищают ваше хранилище идентичности.)

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

Что попадает в sessionStorage?

Только несекретные метаданные регистрации — никогда ключевой материал.

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

Что явно держится за пределами sessionStorage:

  • Identity Seed;
  • выведенные приватные ключи;
  • выходные значения WebAuthn PRF (псевдослучайной функции) — секреты, которые passkey возвращает для разблокировки хранилища;
  • открытый текст хранилища;
  • расшифрованное запечатанное содержимое.

Граница проста. Непрерывность интерфейса может переживать перезагрузку; секреты идентичности — нет.

Чему вообще не место в браузерном хранилище?

Открытый материал идентичности — ни в одном хранилище.

Эти данные держатся вне localStorage, sessionStorage, IndexedDB, cookie, журналов и обычного состояния приложения:

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

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

Что такое режим общедоступного компьютера?

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

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

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

Что означает зануление в JavaScript?

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

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

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

Так что зануление здесь — мера «насколько это возможно», а не гарантированное стирание. Оно ощутимо сокращает окно, в котором задерживается случайная копия; оно не обещает, что байты исчезли везде.

Что если страница скомпрометирована, пока она разблокирована?

Тогда идентичность действительно под угрозой — это самая трудная граница в любой браузерной криптографии.

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

CardanoWall опирается на эшелонированную защиту, чтобы сузить это окно: строгий Content Security Policy, ограничивающий скрипты собственным источником приложения — без встроенных скриптов, без eval и без загрузки каких-либо сторонних скриптов вообще, — плюс заголовки безопасности, проставляемые на каждый ответ на границе сети, сознательно небольшая поверхность секретов, отсутствие сохранения в открытом виде и разблокировка и расшифровка только по явному действию пользователя — никогда автоматически при переключении на вкладку. Это снижает вероятность и радиус поражения. Но это не делает безвредным вредоносный скрипт внутри разблокированного источника; он остаётся самой опасной угрозой, которую браузерная модель принимает как данность.

Для самых чувствительных идентичностей правильный ответ — вынести ключевой материал за пределы совместной веб-поверхности. Держите их на выделенном доверенном устройстве и предпочитайте рабочий процесс, в котором секрет вообще не касается браузера, — CLI в автоматизации или CardanoWall Desktop, который держит ваши ключи в локальном ядре на Rust, а не в веб-источнике. (О более широком принципе читайте в материале почему ключи никогда не покидают устройство.)

Что вам стоит на самом деле делать?

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

Для повседневного использования:

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

Для чувствительной работы добавьте:

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

Коротко

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

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

securitybrowser-securityidentity