Synapolis/DCC Custody Tool

From wikibase

DCC Custody Tool — публичный офлайн-инструмент восстановления данных холодного хранения DCC по схеме 3-из-4. Финальный выпуск поддерживает два совместимых режима хранителя, воспроизводимую сборку и проверяемое сетевое ограничение. Выпуск не подписан и не проходил независимый аудит.

Рекомендуемый способ работы[edit | edit source]

Основной и рекомендуемый интерфейс — командная строка на чистом физически отключённом от сети хосте. CLI делает режим и тип секрета явными, читает секреты из файлов с правами 0600 и удобнее для аудита и повторяемой процедуры.

Однофайловый recover.html — только вторичный офлайн-вариант для удобства. Даже при запрете сети расширения браузера, история, буфер обмена, скомпрометированный профиль или сам браузер могут раскрыть секрет. Нельзя вводить реальные ключи или доли в сетевую копию страницы.

Режимы хранителя и совместимость[edit | edit source]

Каждый хранитель независимо и добровольно выбирает один из режимов:

  • Dedicated age (рекомендуется): отдельная пара ключей age; наружу нужен только публичный получатель age1....
  • Stellar compatibility: существующий публичный G-ключ детерминированно отображается в получателя age, а соответствующий S-ключ открывает уже развёрнутые совместимые конверты.

Принудительной миграции нет. Старые конверты и существующие доли 3-из-4 не изменены и остаются читаемыми. Добавление dedicated-age получателя в будущий набор конвертов потребует отдельной авторизации и согласия хранителя.

Публичный получатель для dedicated-age предложен в черновом BSN-теге:

DCC_CUSTODY_AGE_RECIPIENT_V1 = age1<bech32-recipient>

Статус предложения: DRAFT / NOT ADOPTED / NO LEDGER ACTION. Оно не заменяет Stellar G-ключ, не разрешает пересоздание конвертов и не доказывает владение ключом.

Раздельные парсеры и входы[edit | edit source]

CLI требует явный --mode age или --mode stellar. Identity AGE-SECRET-KEY-1... принимается только отдельным age-парсером и отдельным файлом --age-identity-file. Stellar S-ключ принимается только Stellar-парсером и файлом --stellar-secret-file. Age identity не представляется как Stellar secret и не передаётся в S-key парсер.

Граница совместимости Shamir[edit | edit source]

src/legacy-shamir.js изолирован как legacy-декодер только для чтения. Замена его формата или арифметики новой библиотекой нарушила бы совместимость с уже развёрнутыми долями и потребовала бы их запрещённого перевыпуска. Код нельзя использовать для выпуска новых долей.

Проверки прошли на фиксированной fixture, всех C(4,3) комбинациях, исчерпывающем сравнении операций GF(256) с независимой реализацией и некорректных входах. Эти тесты подтверждают совместимость, но независимого аудита декодера нет.

Сетевое ограничение и CSP[edit | edit source]

В выпуске нет Yandex, аналитики, внешних ресурсов, сетевых API, cookies и браузерных storage API. Runtime network-trap зафиксировал ноль попыток сетевого обращения.

Точное значение HTTP CSP:

default-src 'none'; script-src 'sha256-lbW9/RKTWSsWCiAaTbyNjXSxkwmwnmOV0vA+444xhC0='; style-src 'unsafe-inline'; form-action 'none'; base-uri 'none'; frame-ancestors 'none'

В script-src нет 'unsafe-inline': встроенный сценарий разрешён только точным SHA-256. В style-src 'unsafe-inline' пока остаётся. Meta CSP служит офлайн-страховкой скачанного файла; HTTP-заголовок является серверной политикой.

Статус подписи и аудита[edit | edit source]

Выпуск UNSIGNED. Точный блокер: отсутствуют настроенная авторизованная custody signing identity и независимо аутентифицированная политика подписи с публичным ключом проверки. Конвейер, инструкции подписи и проверки опубликованы в release/; для этого выпуска ключ не создавался. Нельзя утверждать, что выпуск подписан или независимо аудирован.

Самотесты, фиксированные fixtures, runtime confinement и воспроизводимость — проверяемые свидетельства, а не независимый аудит безопасности.

Публичные артефакты[edit | edit source]

Артефакт SHA-256
recover.html fbf803b154aaf075da03463e6db3d183cc3233765fd228ccd40f7be5c0a3736c
custody-src.tar.gz 3e6261e1d7723da76aaf9943f8f381f747b9a51bcfe742854b6d6e57c140e285
SHA256SUMS eecd0c2a7914702e595ffda0041b9174b7b93032a94cc8726cf6259b3b3b8010
CSP.txt 4e74b009a1eedac79d0dfcdcb11b8dc3b3f794f001c32213cc8da389c836eaeb

Исходники и документация: публичный каталог.

Точное воспроизведение и проверка[edit | edit source]

Команды из публичных README и release-документации (Bash, Node 20, Python 3, эталонный age 1.2.1):

curl -fSLO https://aination.center/custody/custody-src.tar.gz
printf '%s  %s\n' \
  '3e6261e1d7723da76aaf9943f8f381f747b9a51bcfe742854b6d6e57c140e285' \
  'custody-src.tar.gz' | sha256sum -c -
mkdir custody-src
tar -xzf custody-src.tar.gz -C custody-src
cd custody-src
sha256sum SHA256SUMS
bash build.sh
bash tests/run.sh
SOURCE_DATE_EPOCH=1787097600 bash release/build-release.sh
bash release/verify-release.sh release/out/custody-hardening-source.tar.gz release/out/SHA256SUMS
SOURCE_DATE_EPOCH=1787097600 OUT_DIR=release/out-a bash release/build-release.sh
SOURCE_DATE_EPOCH=1787097600 OUT_DIR=release/out-b bash release/build-release.sh
sha256sum release/out-{a,b}/custody-hardening-source.tar.gz
cmp release/out-a/custody-hardening-source.tar.gz release/out-b/custody-hardening-source.tar.gz

До проверки архива и сборки реальные секреты использовать нельзя. Точный хеш встроенного сценария берётся из созданного dist/CSP.txt; сервер должен отдавать приведённый выше HTTP CSP.

Семь рассмотренных улучшений[edit | edit source]

  1. CLI как основной путь — реализовано: browser UI сохранён как вторичное офлайн-удобство с явным предупреждением о рисках.
  2. Выделенный age-ключ на хранителя — реализовано опционально и рекомендуется: Stellar-совместимость сохранена, миграция не навязана.
  3. BSN-тег получателя — опубликован только как черновик: DCC_CUSTODY_AGE_RECIPIENT_V1 не принят, действий в ledger не было.
  4. Разделение секретных входов — реализовано: age identity и Stellar S-key имеют разные параметры и парсеры.
  5. Замена custom Shamir — отклонена ради совместимости: legacy decoder изолирован decode-only и расширенно протестирован; независимого аудита нет.
  6. Усиление офлайн-политики — реализовано: Yandex/analytics отсутствуют, network-trap показал ноль попыток, HTTP CSP привязан к точному script hash; inline styles пока разрешены.
  7. Подписанный воспроизводимый выпуск — воспроизводимость реализована, подпись заблокирована: инструкции готовы, но авторизованная signing identity и независимо подтверждённая политика/public key отсутствуют.

См. также[edit | edit source]