Основное (наша работа в этой сессии): - Переименование «subserver» → «homeserver» по всему проекту: основной ESP32-скетч (папка shine_subserver_ui → shine_homeserver_ui, .ino, flash-скрипт, режим burn.sh homeserver-ui), скетч lvgl_nav_minimal_test (ключ homeserver.key:<имя>), spec-доки reference/*, формат PDA (терминология session_type=100 «Homeserver пользователя»), константа SESSION_TYPE_HOMESERVER в JS и Rust (значение 100 не менялось, формат не затронут), pending/future доки, AGENTS.md, DAO-док. Сохранены отдельный lvgl_subserver_touch_test и историческая пометка о рендейме в DERIVATION.md. - Новый источник истины по деривации ключей: Dev_Docs/Keys/DERIVATION.md (Argon2id-секрет из пароля, формула Ed25519(SHA-256(base64(secret)|suffix)), суффиксы root/bch/dev/homeserver.key, Solana-ключ = dev.key). Уточнены роли root (главный/master) и dev (пополняемый кошелёк) в Dev_Docs/Keys/README.md. - UI: убран легаси-путь пустого пароля (derivePasswordSeed и др.), deriveMasterSecretFromPassword бросает ошибку на пустом пароле, register-view блокирует пустой пароль; экран пополнения переведён на канонический device-адрес из preGeneratedKeyBundle (удалён расходящийся deriveWalletFromPassword). Включены также параллельные правки Solana-аудита №3 (были в рабочем дереве, переплетены в lib.rs): - shine_users: defense-in-depth «строгий список аккаунтов» (require!(it.next().is_none())) в init/update economy config и create/update user PDA, плюс описание в doc/programs/shine_users.md; - Dev_Docs/audit/Solana-audit-3-by-Claude-12июня2026.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
177 lines
13 KiB
Markdown
177 lines
13 KiB
Markdown
# Ключи SHiNE
|
||
|
||
Этот документ описывает роли ключей в SHiNE и их связь с Solana, персональным блокчейном, личными сообщениями, сессиями и будущими аппаратными устройствами.
|
||
|
||
Документ является архитектурной справкой. Он не меняет текущие форматы API, DM-блоков или блокчейна сам по себе.
|
||
|
||
## Коротко
|
||
|
||
В SHiNE у пользователя есть несколько уровней ключей:
|
||
|
||
- `root key` - главный (master) ключ пользователя: тот, кто им владеет, управляет пользовательской PDA в Solana и может заменить все остальные ключи. Это не пополняемый кошелёк (комиссии платит `device key`).
|
||
- `blockchain key` - ключ записи в персональный SHiNE-блокчейн пользователя.
|
||
- `device key` - общий ключ пользовательских устройств для повседневной работы, звонков, DM и мелких платежей.
|
||
- `session key` - ключ конкретной сессии или конкретного устройства для авторизации на сервере.
|
||
|
||
Главная идея: самые важные ключи можно держать на доверенном серверном или аппаратном устройстве, а обычные клиентские устройства получают только ключи, нужные для текущей работы.
|
||
|
||
## `root key`
|
||
|
||
`root key` - главный ключ пользователя.
|
||
|
||
Назначение:
|
||
|
||
- регистрация пользователя в Solana;
|
||
- создание и обновление пользовательской PDA-записи;
|
||
- вызов критически важных Solana-функций;
|
||
- изменение главных настроек пользователя;
|
||
- управление остальными ключами;
|
||
- подтверждение операций, которые должны иметь максимальный уровень доверия.
|
||
|
||
`root key` — это **главный (master) ключ** в следующем смысле: зная `root key`, можно управлять пользовательской PDA-записью в Solana (`create_user_pda` / `update_user_pda`) и тем самым **заменить все остальные ключи** пользователя (device, blockchain, homeserver). Поэтому компрометация `root key` равносильна компрометации всей личности пользователя.
|
||
|
||
Важно не путать авторитет и кошелёк: `root key` — это авторитет над PDA-записью, а **SOL-комиссии за create/update платит `device key`** (он же fee payer и адрес для пополнения). Подробнее о том, какой ключ за что отвечает на Solana, — в `Dev_Docs/Keys/DERIVATION.md`, §3.
|
||
|
||
## `blockchain key`
|
||
|
||
`blockchain key` - ключ записи в персональный SHiNE-блокчейн пользователя.
|
||
|
||
Назначение:
|
||
|
||
- подпись записей в персональном блокчейне пользователя;
|
||
- подтверждение действий, которые должны попасть в SHiNE-блокчейн;
|
||
- разделение полномочий между главным Solana-ключом и ключом ежедневной записи.
|
||
|
||
У пользователя может быть несколько персональных блокчейнов или веток. При смене `blockchain key` фактически создаётся новая ветка записи:
|
||
|
||
- `username-001` - первая ветка;
|
||
- `username-002` - вторая ветка;
|
||
- `username-003` - третья ветка.
|
||
|
||
Рабочая логика по умолчанию должна использовать последнюю актуальную ветку. Старые ветки остаются читаемыми и показывают историю смены ключей.
|
||
|
||
## `device key`
|
||
|
||
`device key` - общий ключ, который знают доверенные устройства пользователя.
|
||
|
||
Назначение:
|
||
|
||
- повседневные входящие и исходящие личные сообщения;
|
||
- звонки и связанные с ними сообщения;
|
||
- self-messages, то есть внутренние сообщения пользователя самому себе;
|
||
- мелкие Solana-расходы на текущие операции;
|
||
- derivation Arweave-кошелька;
|
||
- оплата или подготовка добавления данных в Arweave-кошелек по отдельному протоколу.
|
||
|
||
Arweave-кошелёк должен выводиться из `device key` по протоколу:
|
||
|
||
- `Dev_Docs/Протоколы/SHINE_ARWEAVE_DERIVATION_V1.md`
|
||
|
||
Если пользователь теряет только `device key`, в худшем случае ломается повседневная переписка и доступ конкретных устройств к ежедневным операциям. `root key` и `blockchain key` при правильной архитектуре остаются отдельно защищёнными.
|
||
|
||
## `session key`
|
||
|
||
`session key` - уникальный ключ конкретной сессии или устройства.
|
||
|
||
Возможные форматы:
|
||
|
||
- `Ed25519` - предпочтительный современный вариант;
|
||
- `RSA` - legacy-вариант, полезный для устройств, где системное защищённое хранилище хорошо поддерживает RSA-ключи и не позволяет извлекать приватный ключ.
|
||
|
||
Назначение:
|
||
|
||
- авторизация сессии на сервере;
|
||
- привязка устройства к пользователю;
|
||
- подтверждение запросов от конкретной сессии;
|
||
- доступ к зашифрованному `device key` после успешной авторизации.
|
||
|
||
Одна и та же сессия может быть пригодна для подключения к нескольким серверам пользователя, если архитектура конкретного пользователя это допускает.
|
||
|
||
У сессии должны быть:
|
||
|
||
- имя сессии;
|
||
- тип сессии;
|
||
- публичная часть ключа;
|
||
- ссылка на пользователя;
|
||
- информация о сервере или серверах, которым эта сессия доверена.
|
||
|
||
Имя сессии может создаваться автоматически из названия устройства и короткого случайного идентификатора, например `Android-a1b2c3`, `Ubuntu-f47a90`. Пользователь может переименовать сессию.
|
||
|
||
## Типы сессий
|
||
|
||
Базовые типы:
|
||
|
||
- обычная пользовательская сессия;
|
||
- серверная сессия;
|
||
- аппаратная или доверенная сессия с доступом к расширенным ключам.
|
||
|
||
Обычное устройство обычно имеет:
|
||
|
||
- собственный `session key`;
|
||
- зашифрованный `device key`, который открывается после авторизации;
|
||
- доступ к DM, звонкам и обычным пользовательским операциям.
|
||
|
||
Доверенное серверное или аппаратное устройство может иметь:
|
||
|
||
- `root key`;
|
||
- `blockchain key`;
|
||
- `device key`;
|
||
- собственный `session key`.
|
||
|
||
Такая сессия может подписывать операции повышенной важности по запросам пользователя.
|
||
|
||
## Внутренние self-messages
|
||
|
||
Self-message - это сообщение пользователя самому себе.
|
||
|
||
Такие сообщения нужны, чтобы обычное устройство могло попросить доверенное устройство выполнить действие:
|
||
|
||
- подписать запись `blockchain key` и передать её в SHiNE-блокчейн;
|
||
- подписать изменение настройки через `root key`;
|
||
- обновить ключи;
|
||
- сохранить внутреннюю команду или настройку;
|
||
- отправить сообщение другому пользователю с сохранением копии себе;
|
||
- сохранить сообщение только себе.
|
||
|
||
Важно: self-message не является публичной командой сервера. Это пользовательская внутренняя команда, которую сервер или доверенное устройство обрабатывает в рамках прав конкретного пользователя.
|
||
|
||
## Шифрование входящих сообщений
|
||
|
||
Входящее сообщение может быть зашифровано:
|
||
|
||
- `device key`;
|
||
- `session key`;
|
||
- отдельным ключом конкретного чата;
|
||
- другим ключом, который уже известен клиенту.
|
||
|
||
В сообщении не должно быть лишнего раскрытия того, каким именно ключом оно зашифровано. Клиент пробует расшифровать сообщение доступными ключами по порядку. Если расшифровка не удалась, сообщение остаётся непонятным для этого устройства.
|
||
|
||
## Копии сообщений
|
||
|
||
Для отправки сообщений нужны несколько режимов:
|
||
|
||
- сообщение другому пользователю с исходящей копией себе;
|
||
- сообщение другому пользователю без локальной исходящей копии;
|
||
- сообщение только себе.
|
||
|
||
Это должно позволить строить обычные DM, внутренние команды, личные заметки и зашифрованные пользовательские чаты поверх одной общей модели сообщений.
|
||
|
||
## Связанные документы
|
||
|
||
- `Dev_Docs/Keys/DERIVATION.md` - **источник истины по конкретной деривации** секрета и ключей (формулы Argon2id, `base64|suffix→SHA-256→Ed25519`, суффиксы `root.key`/`bch.key`/`dev.key`/`homeserver.key:<имя>`, Solana-ключ, ссылки на код).
|
||
- `Dev_Docs/Personal_Messages/README.md` - текущая документация личных сообщений.
|
||
- `Dev_Docs/Blockchain/README.md` - точка входа по форматам SHiNE-блокчейна.
|
||
- `Dev_Docs/Solana_Architecture/README.md` - архитектура Solana-программ, PDA-счетов, DAO и движения средств.
|
||
- `Dev_Docs/Инициализация_Solana_регистрации/README.md` - деплой и первичная инициализация Solana-регистрации.
|
||
- `Dev_Docs/Протоколы/SHINE_ARWEAVE_DERIVATION_V1.md` - derivation Arweave-кошелька из `device key`.
|
||
|
||
## Что нужно уточнить перед реализацией
|
||
|
||
- точный формат записи списка ключей в Solana PDA;
|
||
- как именно обозначать активную ветку персонального блокчейна;
|
||
- какие операции требуют `root key`, а какие достаточно подписывать `blockchain key`;
|
||
- формат self-message-команд;
|
||
- порядок перебора ключей при расшифровке входящих сообщений;
|
||
- правила ротации `device key` и восстановления доступа после потери устройства;
|
||
- какие типы серверных и аппаратных сессий нужны в первой реализации.
|