Фразы семян BIP39 Что на самом деле означают эти 12 слов и как работает производство кошельков HD

Опубликовано

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

Фразы семян BIP39: Что на самом деле означают эти 12 слов и как работает производство кошельков HD 1
Реклама · УДАЛИТЬ?

Мнемоническая последовательность BIP39 представляет собой 128 или 256 бит случайных данных, закодированных в виде человекочитаемых слов с использованием фиксированного списка из 2048 слов. Это и есть вся суть. «Магия» заключается в том, что слова легче записывать на бумаге, чем шестнадцатеричные строки — криптографически сами слова не имеют особых свойств.

Интересно то, что на этой кодировке построена четырёхуровневая структура: BIP39 (список слов и кодирование), BIP32 (уровневая детерминированная генерация ключей), BIP43 (конвенции по назначению), и BIP44 (структура монет/счетов/адресов). Большинство объяснений смешивают все четыре элемента. В данном случае они разделяются.

Список слов: 11 бит на слово, включая контрольную сумму

The Список английских слов BIP39 имеет ровно 2048 слов. 211 = 2048, поэтому каждое слово кодирует 11 бит информации. Последовательность из 12 слов содержит в общей сложности 132 бита; последовательность из 24 слов содержит 264 бита.

Не все из этих битов являются энтропией. Последние несколько бит последнего слова — это контрольная сумма — первые ENT/32 бит от SHA256(байты энтропии), где ENT — длина энтропии в битах:

Длина последовательностиБиты энтропии (ENT)Биты контрольной суммы (CS = ENT/32)Общее количество битов
12 слов1284132
15 слов1605165
18 слов1926198
21 слово2247231
24 слова2568264

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

Сопоставление энтропии с словами на Python:

import hashlib, os

# Generate 128 bits of entropy
entropy = os.urandom(16)  # 16 bytes = 128 bits

# Compute checksum: first 4 bits of SHA256(entropy)
h = hashlib.sha256(entropy).digest()
checksum_bits = format(h[0], '08b')[:4]  # first 4 bits of SHA256 output

# Combine entropy bits + checksum bits
all_bits = format(int.from_bytes(entropy, 'big'), '0128b') + checksum_bits
# all_bits is now 132 bits

# Split into 11-bit groups -> 12 word indices (0-2047)
word_indices = [int(all_bits[i:i+11], 2) for i in range(0, 132, 11)]
# Look up each index in the BIP39 word list to get the mnemonic

Мнемоническая последовательность не является ключом: шаг PBKDF2

Здесь большинство объяснений ошибаются. 12 слов не являются вашим приватным ключом и не используются напрямую для подписи. Это промежуточное кодирование. Перед генерацией любого ключевого материала мнемоническая последовательность подвергается расширению через PBKDF2-HMAC-SHA512:

import hashlib

mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
passphrase = ""  # optional; empty string = no passphrase

seed = hashlib.pbkdf2_hmac(
    'sha512',
    mnemonic.encode('utf-8'),                    # password: the mnemonic words
    ('mnemonic' + passphrase).encode('utf-8'),   # salt: always "mnemonic" + passphrase
    2048,                                         # iterations
    dklen=64                                      # 512 bits output
)
# seed is 64 bytes (512 bits) -- this is what actually seeds key derivation

Два важных момента:

  • Соль всегда является буквальным строковым значением "mnemonic" конкатенированным с паролем. Пустой пароль означает, что соль — это просто "mnemonic" — нет отдельного режима «без пароля».
  • Пароль полностью меняет получаемый сид. Тот же 12-словный набор слов с паролем "A" vs "a" приводит к совершенно другим кошелькам с совершенно другими адресами. Это и есть «25-е слово»: пароль позволяет поддерживать убедительную неприкосновенность (два кошелька из одного набора слов), но потеря пароля является необратимой, даже при наличии 12 слов.

От сид до основного ключа: BIP32

512-битный сид подаётся в HMAC-SHA512 с фиксированной строкой "Bitcoin seed". 64-байтовый выход делится на две части по 256 бит:

import hmac, hashlib

master = hmac.new(b'Bitcoin seed', seed, hashlib.sha512).digest()
master_private_key = master[:32]   # left 256 bits: the actual EC private key
master_chain_code  = master[32:]   # right 256 bits: used for all child derivation

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

Вместе, master_private_key + master_chain_code формируют основной расширенный приватный ключ, закодированный как xprv... строка Base58Check. Соответствующий расширенный публичный ключ — xpub... — полезен для кошельков-наблюдателей, которые должны генерировать адреса без раскрытия приватных данных.

Путь генерации BIP44: m/44’/60’/0’/0/0 декодирован

BIP44 определяет пятиуровневую иерархию генерации. Вот m/44’/60’/0’/0/0 — стандартный путь первого адреса для Ethereum — распадается по компонентам:

УровеньЦенитьШестнадцатеричный индексЗначение
mКорень основного ключа
44'назначение0x8000002CНазначение BIP44. Упрочнённое (апостроф = 0x80000000 + индекс).
60'тип монеты0x8000003CEthereum, согласно SLIP-0044. Bitcoin = 0′, Solana = 501′, и т.д.
0'счет0x80000000Первый счет. Увеличивается для изолированных счетов.
0изменение0Внешняя цепь (0 = адреса получения, 1 = адреса изменения). Кошельки редко используют цепь изменения для EVM-цепей.
0индекс0Индекс адреса. Увеличивается для второго адреса, третьего и т.д.

Апострофы обозначают упрочнённое производство. Упрочнённые дочерние ключи могут быть получены только из родительского приватного ключа, а не из родительского публичного ключа. Это важно, потому что при обычном (неупрочнённом) производстве, если компрометирован дочерний приватный ключ и родительский публичный ключ, то можно раскрыть родительский приватный ключ и все сестринские ключи. На уровнях назначения, типа монеты и счета упрочнённое производство является стандартом.

Почему одинаковая последовательность даёт разные адреса в разных кошельках

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

Для Ethereum основное разделение:

  • MetaMask, Ledger Live, большинство современных кошельков: m/44'/60'/0'/0/N — стандартный BIP44.
  • MyEtherWallet (старый стандарт): m/44'/60'/0'/N — на один уровень короче. Кошелек, восстановленный из той же последовательности в MEW с помощью старого пути, генерирует совершенно другой набор адресов по сравнению с MetaMask.
  • Trezor Suite: Следует стандартному BIP44 для ETH сейчас, но исторически имел свои особенности с некоторыми альткошельками.

Для Bitcoin разногласие структурное: BIP44 (m/44'/0'/0', старый P2PKH, адреса начинаются с 1), BIP49 (m/49'/0'/0', P2SH-P2WPKH, адреса начинаются с 3), и BIP84 (m/84'/0'/0', интегрированный segwit P2WPKH, адреса начинаются с bc1q) генерируют разные адреса из одного сид. Формат адреса показывает, какой путь был использован, поэтому формат адреса важен при устранении неисправностей восстановления.

Если вы импортируете последовательность и «денежные средства отсутствуют», проверьте путь генерации перед тем, как предполагать, что последовательность неверна. Большинство кошельков позволяют вручную указать путь при продвинутом импорте.

Режимы уязвимости безопасности

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

Фишинг: «введите вашу последовательность восстановления, чтобы продолжить»

Наиболее частый вид атак. Фальшивые интерфейсы кошельков, встроенные браузерские расширения с вредоносными скриптами, имитаторы поддержки клиентов в Discord — все просили пользователей ввести свои 12 слов где-то. Правильная модель мышления: легитимное программное обеспечение кошелька никогда не просит вас ввести последовательность восстановления после первоначальной настройки. Запрос о последовательности — это атака, независимо от того, насколько реалистично выглядит интерфейс.

Мониторинг буфера обмена

Вредоносное ПО, которое периодически проверяет буфер обмена, обнаруживает последовательность из 12 или 24 известных слов BIP39 и передаёт её. Время передачи — миллисекунды. Копирование последовательности в любом месте — даже кратковременно в текстовом редакторе — создаёт уязвимость. Управление историей буфера обмена (Windows Clipboard History, macOS clipboard managers, IDE paste history) особенно опасны.

Скриншоты и синхронизация облачных фото

Сделанный скриншот последовательности на телефоне загружается в iCloud Photos или Google Photos через несколько секунд, до того как большинство людей прочитают её. Эти резервы не зашифрованы на клиентской стороне. «Я сделал скриншот, чтобы сохранить его» — это прямой путь к утечке. Физически безопасное бумажное резервирование — не шутка.

Генерация последовательности на сервере

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

Если вам нужно проверить или убедиться в структуре последовательности — проверить энтропию, увидеть сид, проверить путь — то Конвертер BIP39 Mnemonic работает полностью в браузере. Последовательность никогда не покидает ваше устройство, что является единственной архитектурой, безопасной для этого случая.

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

Если вы разрабатываете приложение, связанное с криптовалютой, интуиция «обрабатывать последовательность в бэкенде» почти всегда ошибочна. Площадь атаки:

  • Логирование. Каждая веб-фреймворк логирует тело запроса где-то. Один лог-строк, одна неправильно настроенная лог-уровень, и каждая последовательность, прошедшая через ваш API, находится на диске — бесконечно, в нескольких лог-целевых, которые вы не проверяли.
  • Передача. HTTPS защищает сеть. Он не защищает балансировщик нагрузки, процесс памяти бэкенда, базу данных или агрегатор логов. Каждый из них — отдельная уязвимость.
  • Память. Процессные дампы, отчёты об авариях, файлы краха и снимки памяти захватывают строки в памяти. Последовательность в Python dict или JavaScript объекте не является нулевым копированием; она, скорее всего, появляется в нескольких выделениях до того, как она «удаляется».
  • Ответственность. Если ваш бэкенд обрабатывает последовательности пользователей и произойдёт проникновение, ущерб будет необратимым. В отличие от паролей, нет механизма сброса. Пострадавшие пользователи теряют средства без возможности восстановления.

Архитектура, которая работает: производите то, что вам нужно, на клиентской стороне и передавайте только результат — публичный ключ, только для чтения xpub, подписанную транзакцию. Бэкенд никогда не видит последовательность. Библиотеки, которые делают это правильно: @scure/bip39 (проверенные, минимальные зависимости), ethers.jsи bitcoinjs-lib. Для интеграции с аппаратными кошельками, SDK Trezor и Ledger возвращают подписанную транзакцию — ключ никогда не покидает устройство.

Полная цепочка генерации на одном взгляд

ШагВходОперацияВыход
1. Энтропия128–256 случайных битSHA256 контрольная сумма → группы из 11 бит12–24 слово мнемонической последовательности
2. СидСлова мнемоники + «mnemonic» + парольPBKDF2-HMAC-SHA516, 2048 итераций512-битный сид (64 байта)
3. Основной ключБайты сидHMAC-SHA512(«Bitcoin seed», сид)Основной приватный ключ (256 бит) + код цепи (256 бит)
4. Ключ аккаунтаОсновной ключ + путь m/44’/60’/0’Упрочнённое производство дочерних ключей BIP32 × 3Расширенный приватный ключ аккаунта
5. Ключ адресаКлюч аккаунта + путь /0/NУпрочнённое производство дочерних ключей BIP32 × 2Дочерний приватный ключ → secp256k1 публичный ключ → keccak256 → адрес

BIP39 сделал то, что было задумано: сделал энтропию записываемой и восстановимой. Площадь атаки не в криптографии — PBKDF2 с 2048 итерациями, HMAC-SHA512, secp256k1 — всё это надёжно. Атаки полностью операционные: ввод последовательности в неподходящее место, хранение её цифрово, доверие инструменту, генерирующему её на сервере. Математика в порядке. Слабым звеном являются люди, поэтому рекомендация для разработчика — архитектурировать систему так, чтобы последовательность никогда не касалась вашей инфраструктуры.

Хотите убрать рекламу? Откажитесь от рекламы сегодня

Установите наши расширения

Добавьте инструменты ввода-вывода в свой любимый браузер для мгновенного доступа и более быстрого поиска

в Расширение Chrome в Расширение края в Расширение Firefox в Расширение Opera

Табло результатов прибыло!

Табло результатов — это интересный способ следить за вашими играми, все данные хранятся в вашем браузере. Скоро появятся новые функции!

Реклама · УДАЛИТЬ?
Реклама · УДАЛИТЬ?
Реклама · УДАЛИТЬ?

новости с техническими моментами

Примите участие

Помогите нам продолжать предоставлять ценные бесплатные инструменты

Купи мне кофе
Реклама · УДАЛИТЬ?