1. Главная
  2. / BIP39 по-русски
  3. / Сид-фраза и приватный ключ: в чём разница и что сохранить
Опубликовано

Сид-фраза и приватный ключ: в чём разница и что сохранить

Сид-фраза и приватный ключ дают доступ к криптовалюте, но на разных уровнях. Сид-фраза (seed-фраза, мнемоническая фраза, фраза восстановления) — это 12–24 слова, из которых кошелёк вычисляет все свои приватные ключи: для каждого аккаунта, монеты и адреса, включая те, которыми вы ещё не пользовались. Приватный ключ — одно 256-битное число, которое управляет одним адресом, а в Ethereum и других EVM-сетях — одним аккаунтом. Из фразы всегда можно заново получить любой выведенный из неё ключ, а из ключа фразу — нельзя. Ниже — сравнительная таблица, путь от публичной тестовой фразы до первого биткоин-адреса и ответы на практические вопросы: что восстанавливает фраза, а что ключ, как быть, если у вас есть только ключ, чем рискован экспорт ключей и что хранить в резервной копии. Если термин для вас новый, начните со статьи что такое сид-фраза.

Сид-фраза и приватный ключ: сравнение

Сид-фразаПриватный ключ
Что этоСлова, которыми записана случайная энтропия; из неё строится иерархический детерминированный (HD) кошелёкОдно секретное число, которым подписываются переводы с одного адреса или аккаунта
Чем управляетВсеми аккаунтами, монетами и адресами, которые из неё выводятся, включая будущиеТолько адресом или аккаунтом, вычисленным из этого ключа
ФорматСлова из списка BIP39 на 2048 слов, почти всегда английскогоBitcoin — WIF, строка в кодировке Base58; Ethereum — 64 шестнадцатеричных символа; иногда — зашифрованный файл
Длина12, 15, 18, 21 или 24 слова: от 128 до 256 бит энтропии плюс контрольная сумма256 бит: 64 шестнадцатеричных символа или строка WIF из 52 символов, начинающаяся с K или L (у несжатого ключа — из 51 символа, начинающаяся с 5)
Как используетсяКошелёк показывает её при создании, чтобы вы её записали, и снова просит только при восстановленииКошелёк вычисляет его из сида и подписывает им транзакции; показывает только через функцию экспорта
Что сохранятьСаму фразу и парольную фразу, если она заданаТолько ключи, которые не выводятся из вашей фразы: импортированные аккаунты, бумажные кошельки

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

Названия в приложениях бывают разные. В русской версии MetaMask приватный ключ называется «Закрытый ключ» (Private key), сид-фраза — «Секретная фраза для восстановления» (Secret Recovery Phrase), а аккаунт — «Счет» (Account).

Как из сид-фразы получаются приватные ключи

Значения ниже получены из публичной тестовой фразы BIP39 (abandon одиннадцать раз и about в конце) без парольной фразы. Ту же фразу используют тестовые векторы BIP84. Фраза известна всем, поэтому никогда не отправляйте средства на её адреса.

  1. От слов к энтропии. Каждое слово несёт 11 бит, поэтому 12 слов вмещают 128 бит энтропии и 4 бита контрольной суммы. Тестовая фраза кодирует энтропию из одних нулей, а из-за битов контрольной суммы последним словом становится about.
  2. От слов к сиду. Функция PBKDF2-HMAC-SHA512 с 2048 итерациями превращает слова в 64-байтовый сид; солью служит строка «mnemonic» плюс необязательная парольная фраза.
  3. От сида к главному ключу. По стандарту BIP32 кошелёк вычисляет HMAC-SHA512 от сида с ключом «Bitcoin seed»: левая половина результата становится главным приватным ключом, правая — цепным кодом (chain code). Вместе они образуют главный расширенный приватный ключ — xprv.
  4. От главного ключа к нужному. Путь деривации выбирает ключ в дереве: m/84'/0'/0'/0/0 — первый адрес для получения в первом аккаунте с нативным SegWit.
  5. От ключа к адресу. Из приватного ключа вычисляется публичный ключ, а из хеша публичного ключа — адрес.
Фраза           abandon abandon abandon abandon abandon abandon
                abandon abandon abandon abandon abandon about
Энтропия        00000000000000000000000000000000
Сид             5eb00bbddcf069084889a8ab9155568165f5c453ccb85e70811aaed6f6da5fc1
                9a5ac40b389cd370d086206dec8aa6c43daea6690f20ad3d8d48b2d2ce9e38e4
Главный xprv    xprv9s21ZrQH143K3GJpoapnV8SFfukcVBSfeCficPSGfubmSFDxo1kuHnLisriDvSnRRuL2Qrg5ggqHKNVpxR86QEC8w35uxmGoggxtQTPvfUu
Путь            m/84'/0'/0'/0/0
Приватный ключ  4604b4b710fe91f584fff084e1a9159fe4f8408fff380596a604948474ce4fa3
WIF             KyZpNDKnfs94vbrwhJneDi77V6jF64PWPF8x5cdJb8ifgg2DUc9d
Публичный ключ  0330d54fd0dd420a6e5f8d3624f5f3482cae350f79d5f0753bf5beef9c2d91af3c
Адрес           bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu

Значения вычислены с помощью библиотек @scure/bip39, @scure/bip32 и @scure/btc-signer. Ключ WIF, публичный ключ и адрес совпадают с тестовыми векторами BIP84, где тот же главный ключ записан как zprv. Те же шаги от сида до адреса для любой тестовой фразы показывает конвертер сид-фразы в приватный ключ. Вводите туда только тестовые фразы, настоящую — никогда.

Одна фраза — много ключей

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

ПутьЧто этоАдрес
m/84'/0'/0'/0/0Bitcoin, нативный SegWit, первый адрес для полученияbc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu
m/84'/0'/0'/0/1Bitcoin, нативный SegWit, второй адрес для полученияbc1qnjg0jd8228aq7egyzacy8cys3knf9xvrerkf9g
m/44'/0'/0'/0/0Bitcoin, Legacy, первый адрес для получения1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA
m/44'/60'/0'/0/0Ethereum, первый аккаунт0x9858EfFD232B4033E47d90003D41EC34EcaEda94

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

Где здесь расширенные ключи

Между фразой и отдельным ключом есть промежуточное звено — расширенные ключи. Главный xprv выводит то же дерево BIP32, что и сид, а xprv аккаунта — все ключи одного аккаунта, поэтому любой из них берегите так же, как фразу. Публичная половина xprv аккаунта — xpub — позволяет видеть все адреса аккаунта, но не тратить средства. Префиксы xpub, ypub и zpub разобраны в той же статье о пути деривации.

Что восстанавливает фраза, а что ключ

Сид-фраза: весь кошелёк

Совместимый кошелёк по введённой фразе заново вычислит все ключи и сможет найти аккаунты и адреса, которыми вы пользовались, во всех поддерживаемых им сетях. MetaMask формулирует разницу прямо: секретная фраза для восстановления импортирует весь кошелёк со всеми аккаунтами, а приватный ключ — один аккаунт (справка MetaMask).

Условий два. Парольная фраза, если вы её задавали, должна совпасть до символа, а новый кошелёк должен просматривать те же пути деривации, что и старый. Иначе верная фраза откроет пустой кошелёк; что проверить в этом случае, рассказано в статье как восстановить кошелёк по сид-фразе.

Приватный ключ: один адрес или аккаунт

Приватный ключ восстанавливает ровно то, чем управляет. В Ethereum адрес — это последние 20 байт хеша Keccak-256 от публичного ключа (ethereum.org), поэтому один ключ даёт один адрес, одинаковый во всех EVM-сетях. В Bitcoin из одного ключа строятся адреса Legacy, вложенного SegWit и нативного SegWit. Это разные адреса с отдельными балансами, а строка WIF не хранит, каким из них вы пользовались.

Импортированные аккаунты во фразу не входят

Фраза восстанавливает только выведенные из неё ключи, а всё, что добавлено со стороны, остаётся вне её резервной копии. MetaMask предупреждает об этом прямо в окне импорта: «Импортированные счета не будут связаны с вашей секретной фразой для восстановления MetaMask». В справке MetaMask уточняется, что такие аккаунты не выводятся из фразы и при восстановлении по ней сами не появятся. Вернуть аккаунт, импортированный по приватному ключу, можно только повторным импортом этого ключа (если восстановились не те аккаунты). Исключение — кошельки, созданные через вход с аккаунтом Google, Apple или Telegram: импортированные в них кошельки и ключи привязываются к этому аккаунту и синхронизируются на всех устройствах с тем же входом.

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

Если у вас есть только приватный ключ

Некоторые ключи не выводятся из вашей сид-фразы:

  • Бумажные кошельки. Приватный ключ и адрес, напечатанные на бумаге. Иногда вместо обычного ключа там ключ BIP38 — строка из 58 символов, которая начинается с 6P; к ней нужен ещё и пароль.
  • Файлы keystore JSON. Формат Ethereum Web3 Secret Storage версии 3 хранит приватный ключ, зашифрованный с помощью пароля (обычно шифром AES-128-CTR), поэтому для доступа нужны и файл, и пароль.
  • Экспортированные и импортированные ключи. Ключ, перенесённый из одного кошелька в другой, например в MetaMask через «Добавить кошелек» (Add wallet) → «Импортировать счет» (Import an account), становится отдельным аккаунтом, который фраза нового кошелька не покрывает.

Лучше всего перевести такие средства на адреса, которые выводятся из вашей фразы. В EVM-сети просто отправьте их на один из аккаунтов этой фразы. Комиссия оплачивается основной монетой сети (в Ethereum — ETH), поэтому, пока на старом адресе остаются токены, держите на нём немного этой монеты.

В Bitcoin средства с такого ключа переводят целиком — эта операция называется sweep: все монеты, которыми управляет ключ, отправляются на адрес вашего кошелька. В Electrum это пункт «Кошелёк» → «Приватные ключи» → «Импорт» (Wallet → Private keys → Sweep). Название сбивает с толку: в русском переводе Electrum словом «Импорт» назван и настоящий импорт ключей (Import). Но Sweep ключ в кошелёк не добавляет: монеты уходят на адрес, вычисленный из сида вашего кошелька (FAQ Electrum). В кошельке с сидом пункта Import в этом меню нет, так что «Импорт» там — именно Sweep.

Обычный WIF-ключ Electrum считает ключом адреса Legacy (1…), поэтому для адреса SegWit допишите перед ключом тип скрипта — p2wpkh: для адреса bc1q… или p2wpkh-p2sh: для адреса 3…, как показывают примеры, которые открывает кнопка «Информация» (Info) в окне «Импорт приватных ключей» (Sweep private keys). После этого для всех средств достаточно одной резервной копии — сид-фразы.

По приватному ключу сид-фразу не восстановить

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

  • От слов к сиду. BIP39 прямо пишет: сид получается хешированием фразы, поэтому преобразование идёт только от фразы к сиду.
  • От родителя к потомку. По BIP32 даже дочерний расширенный приватный ключ вместе с его номером не позволяет найти приватный ключ родителя быстрее, чем перебором, требующим 2²⁵⁶ вычислений HMAC-SHA512.
  • Усиленные уровни. Уровни purpose, coin type и account в пути BIP44 усиленные (hardened), поэтому даже уязвимость из следующего раздела останавливается на уровне аккаунта.

Остерегайтесь инструментов, которые «конвертируют» приватный ключ в 24 слова. 32-байтовый ключ действительно можно записать как энтропию BIP39, но кошелёк вычислит из этих слов новый сид и выведет из него совсем другие ключи. Для тестового ключа выше это проверено: с ним не совпал ни один из первых 50 ключей для получения и 50 ключей для сдачи первого аккаунта на каждом из четырёх стандартных путей Bitcoin — BIP44, BIP49, BIP84 и BIP86. Если у вас есть только ключ, храните его как ключ или переведите средства в кошелёк с новой фразой.

Чем опасен экспорт отдельных ключей

Экспортированный ключ нельзя сменить или отозвать, а раскрыть он может больше, чем свой адрес. BIP32 предупреждает: расширенный публичный ключ родителя вместе с любым приватным ключом, выведенным из него только обычными (неусиленными) шагами, равносилен расширенному приватному ключу родителя. А xpub аккаунта часто отдают кошелькам «только для просмотра» (watch-only) и платёжным серверам. Если ваш xpub уже утёк, а затем утечёт и экспортированный ключ одного адреса, раскрыт будет весь аккаунт.

На тестовой фразе это занимает несколько строк кода: xpub аккаунта m/84'/0'/0' и WIF-ключ адреса …/0/0 восстанавливают xprv аккаунта, из которого выводятся все ключи для получения и для сдачи:

xprv9ybY78BftS5UGANki6oSifuQEjkpyAC8ZmBvBNTshQnCBcxnefjHS7buPMkkqhcRzmoGZ5bokx7GuyDAiktd5HemohAU4wV1ZPMDRmLpBMm

Ущерб ограничивает усиленная деривация: по BIP32 утечка приватных ключей уровня аккаунта и ниже никогда не угрожает главному ключу и другим аккаунтам. Но важно, что считать аккаунтом. MetaMask выводит все аккаунты Ethereum, которые создаёт из фразы, как пронумерованные обычные дочерние ключи одной ветки m/44'/60'/0'/0 (код MetaMask). Поэтому один экспортированный ключ аккаунта вместе с расширенным публичным ключом этой ветки раскрыл бы их все.

Экспорт рискован и сам по себе: ключ проходит через экран и буфер обмена. Справка MetaMask прямо называет экспорт приватного ключа рискованным из-за атак на буфер обмена, а расширение MetaMask после копирования ключа предупреждает, что он остаётся в буфере обмена, и предлагает буфер очистить. Ключ, вставленный в другое приложение, — это ещё один экземпляр секрета, о котором резервная копия фразы ничего не знает. Чтобы перевести средства, лучше отправить обычную транзакцию из кошелька: секрет при этом его не покидает. Если без экспорта не обойтись, шаги для MetaMask, Trust Wallet и Electrum собраны в руководстве по экспорту ключей (на английском).

Что сохранять: фразу или ключи

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

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

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

Сид-фраза и приватный ключ — одно и то же?

Нет. Сид-фраза — главная резервная копия, из которой кошелёк вычисляет все приватные ключи. Приватный ключ — один из этих ключей, и управляет он одним адресом или аккаунтом.

Можно ли узнать сид-фразу по приватному ключу?

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

Можно ли импортировать приватный ключ в кошелёк с сид-фразой?

Зависит от кошелька. MetaMask добавит ключ как импортированный аккаунт, который фраза не восстановит. Electrum в кошельке с сидом импорт скрывает, а его FAQ советует вместо этого перевести средства с ключа через Sweep. В обоих случаях сохраните ключ отдельно или переведите его средства на адреса, выведенные из фразы.

Нужно ли сохранять приватные ключи, если есть сид-фраза?

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

Можно ли проверить ключи в онлайн-конвертере?

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