Вернуться в блог
Безопасность

Энтропия кошелька: чему инцидент с Coldcard учит о случайности

Исправление от 27 октября 2026 года. В предыдущей версии статьи говорилось, что уязвимость появилась в прошивке Coldcard 4.0.0, исправленные версии были указаны только для Mk4, Mk5 и Q, а сиды, защищённые passphrase BIP39, назывались не подверженными риску. В бюллетене Coinkite первой затронутой версией для Mk2/Mk3 названа 4.0.1, а исправлением для этих моделей — 4.2.0; там же предупреждается, что слабую passphrase можно подобрать, и пользователям passphrase рекомендуется мигрировать как можно скорее. Число бит для сидов Mk2/Mk3 бюллетень не приводит. Мы исправили соответствующие места. Актуальные рекомендации смотрите в бюллетене безопасности Coinkite и на странице статуса безопасности COLDCARD.

31 июля 2026 года в 01:31 UTC биткоин начал уходить с кошельков, чьи владельцы не сделали ровным счётом ничего. К 01:56 — двадцать пять минут спустя — около 594 BTC, примерно $38 млн, были выведены приблизительно с 500 кошельков с одной подписью. Более поздний анализ Galaxy Research и материалы Chainalysis связали с инцидентом до примерно 1 083 BTC на порядка 1 196 адресах. Никого не фишили. Никто не устанавливал вредоносное ПО. Никто не одобрял транзакцию. Единственное, что объединяло пострадавших, — дата создания их кошелька, потому что отказала энтропия кошелька: случайность, из которой делается сид-фраза, зафиксированная в первую секунду жизни кошелька.

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

Уязвимость 2021 года, обналиченная в 2026-м

Согласно бюллетеню безопасности Coinkite, ошибка прошивки ослабила генерацию сида на Coldcard Mk2 и Mk3 с прошивками от 4.0.1 до 4.1.9 включительно — диапазон начинается с 4.0.1, вышедшей в марте 2021 года, — а также на Mk4, Mk5 и Q с версиями старше исправленных. Страница статуса безопасности Coldcard описывает исправление как удаление программного запасного пути (fallback) в цепочке генерации случайных чисел. Сид-фраза BIP39 должна кодировать 128 бит энтропии — 2¹²⁸ возможных сидов, пространство, которое не переберёт ни один злоумышленник. Бюллетень оценивает затронутые сиды Mk4, Mk5 и Q примерно в 72 бита и называет последствия для старых Mk2/Mk3 более серьёзными; числа бит для этих моделей он не приводит, поэтому примерно 40 бит, которые эта статья использует для затронутых сидов Mk3, — оценка, а не цифра из бюллетеня. 2⁴⁰ — это около 1,1 триллиона кандидатов: колоссально для человека, полностью перебираемо для машины. Вот вся уязвимость Coldcard в одном предложении: генерация сида тихо лишилась большей части своей случайности, и ничто видимое этого не выдало.

Две группы пользователей оказались под гораздо меньшим риском. Надёжная уникальная passphrase BIP39 добавляет независимый барьер: по словам бюллетеня, одной лишь сниженной энтропии сида недостаточно, чтобы добраться до кошелька с passphrase. Но короткую, распространённую, шаблонную или повторно используемую passphrase можно подобрать, а никакая passphrase не исправляет слабый сид под ней, поэтому Coinkite советует пользователям passphrase тоже мигрировать как можно скорее. Сиды, созданные как минимум из 50 честных, независимых, никому не известных бросков кости, не подвержены риску от одной только этой проблемы; при меньшем числе бросков или неуверенности в записях производитель советует мигрировать. Coinkite раскрыла проблему и выпустила исправленную прошивку — 4.2.0 для Mk2 и Mk3; на стандартной ветке 5.6.0 для Mk4 и Mk5 и 1.5.0Q для Q; на ветке Edge — 6.6.0X и 6.6.0QX. Все пять лет между этими точками затронутые кошельки работали безупречно и выглядели неотличимо от безопасных. Тому, кто провёл эту зачистку, ни разу не понадобилось касаться жертв: перебрать слабое пространство ключей, вывести адреса, сопоставить их с блокчейном и перевести всё за одно 25-минутное окно.

Тихая деградация энтропии: почему сиды выглядели случайными

Тревожнее всего то, что в затронутых сидах никогда ничего не выглядело неправильным. Сид, построенный из 40 бит предсказуемого материала, всё равно выходит в виде двенадцати совершенно обычных слов BIP39 с корректной контрольной суммой. Кошелёк принимает его, выводит адреса, подписывает транзакции; каждый экран показывает ровно то, что показал бы сильный кошелёк.

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

Слабый сид не выглядит слабым. Разница между 2¹²⁸ и 2⁴⁰ существует только в коде, который создал эти слова.
Генерация сида разветвляется на путь аппаратного CSPRNG с 2 в степени 128 возможностями и путь тихого отката, засеянный несекретными данными чипа, с 2 в степени 40 возможностями, и оба пути заканчиваются двенадцатью нормально выглядящими словами
Оба пути заканчиваются двенадцатью обычными словами. Разница — 2¹²⁸ против 2⁴⁰ возможных сидов — не появляется ни на одном экране.

Именно поэтому этот класс ошибок живёт годами — и поэтому инцидент с Coldcard принадлежит к целому семейству. Milk Sad в инструменте bx из Libbitcoin, генератор MT19937 в браузерном расширении Trust Wallet, Cake Wallet, инструмент генерации vanity-адресов Profanity и Randstorm в ранних браузерных кошельках имеют одну и ту же форму: CSPRNG, тихо подменённый предсказуемым источником, — без ошибки, без предупреждения, без видимой разницы, пока кто-нибудь не переберёт пространство ключей.

Неудобный урок

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

Не менее важно и то, что Coinkite раскрыла уязвимость и оперативно выпустила исправленную прошивку. Это не история о небрежном вендоре; это режим отказа, который индустрия переоткрывает снова и снова — и в железе, и в софте. Любой кошелёк — включая наш — находится в одном тихом откате от того же класса ошибок. Честный вопрос не «какой вендор неуязвим?», а «как именно откажет этот кошелёк — и заметит ли это хоть кто-нибудь?».

Пять вопросов о случайности любого кошелька

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

  1. Каков источник энтропии? Сид должен происходить из CSPRNG, а не из меток времени, идентификаторов устройства или чего-либо ещё, что мог бы реконструировать посторонний.
  2. Что происходит, если этот источник отказывает? Приемлемый ответ — жёсткая ошибка, останавливающая создание кошелька. Неприемлемый — тихая замена: тихий откат и есть определяющая черта этого класса ошибок.
  3. Открыт ли исходный код пути генерации и можно ли его проверить? Слабая энтропия невидима в выводе, поэтому ревью кода — единственное место, где её можно поймать.
  4. Поддерживает ли кошелёк passphrase BIP39? Passphrase добавляет секретный материал, которого генератор устройства никогда не касался. На затронутых Coldcard надёжная уникальная passphrase означала, что одного ослабленного сида недостаточно, чтобы добраться до средств, — но слабую или повторно используемую passphrase можно подобрать, и никакая passphrase не исправляет слабый сид.
  5. В мультиподписи — генерируются ли ключи на независимых устройствах? Независимые устройства означают независимую случайность: один дефектный генератор компрометирует один ключ, а не кворум.

Как Ownbit генерирует энтропию

Подобные вопросы заслуживают конкретных ответов и о нашем собственном продукте. Генерация мнемонической фразы в Ownbit имеет два слоя. На уровне приложения generateMnemonicRandom(entropy, langIndex) вызывает generateMnemonic из стандартной библиотеки bip39 — 128 бит энтропии по умолчанию и поддержка восьми списков слов BIP39: английского, упрощённого и традиционного китайского, японского, французского, итальянского, корейского и испанского. На уровне библиотеки randomBytes в bip39 черпает случайность из crypto.getRandomValues — платформенного CSPRNG.

Важно здесь то, что происходит, когда этот источник недоступен: библиотека выбрасывает ошибку. Она не обращается ни к часам, ни к идентификатору чипа, ни к какому-либо вторичному источнику — пути отката в коде просто нет. Режим отказа — громкая ошибка в момент создания, и никогда — тихо ослабленный сид. Это свойство — падать громко и никогда не откатываться — прямая противоположность уязвимости, стоявшей за инцидентом с Coldcard, Milk Sad и Randstorm, где генерация тихо продолжала работу от предсказуемого источника.

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

Почему независимо сгенерированные ключи переживают этот класс ошибок

Зачистка 31 июля ударила по кошелькам с одной подписью: один сид, одна подпись — и средств нет; хрестоматийный случай того, как сид-фраза становится единой точкой отказа. Мультиподпись меняет арифметику. В MultiSig-кошельке Ownbit каждый ключ — это собственная стандартная сид-фраза BIP39, сгенерированная на устройстве самого участника. Предположим, одно из устройств несло ровно этот класс уязвимости. В кошельке 2-из-3 злоумышленник, перебравший слабое пространство ключей, держит один ключ — ниже порога. Ничего не движется. Слабый ключ становится задачей обслуживания — заменить его, — а не потерей.

Мультиподпись 2-из-3 с ключами, сгенерированными на трёх независимых устройствах: злоумышленник взламывает единственный ключ со слабой энтропией, но держит лишь 1 из 3 — ниже порога, поэтому средства остаются нетронутыми
Один слабый ключ соподписанта даёт злоумышленнику 1 из 3 — ниже порога. Средства не двигаются.

Защиту даёт независимость, а не слово «мультиподпись». Три ключа соподписантов, сгенерированные на одной и той же дефектной модели устройства, отказали бы вместе. Три ключа, родившиеся на по-настоящему разных устройствах — ваш повседневный телефон, запасной телефон, который держат офлайн как холодный кошелёк с подписанием по QR, устройство члена семьи, — не зависят от генератора одного устройства, поэтому один дефектный генератор ослабляет один ключ, а не все три. Но эта независимость не абсолютна: устройства с одним и тем же кошельковым ПО или библиотекой всё равно могут разделять один сценарий отказа, поэтому код генерации важен не меньше, чем железо. Та же логика объясняет, почему надёжная уникальная passphrase BIP39 защитила затронутых пользователей Coldcard: passphrase — это секретный материал, который ГСЧ устройства никогда не производил, поэтому одного перебора ослабленных сидов для трат оказалось недостаточно. Эта защита сильна ровно настолько, насколько сильна passphrase, а сид под ней остаётся слабым — поэтому производитель всё равно советует мигрировать.

Если у вас затронутый Coldcard

Три действия. Авторитетным источником остаётся бюллетень Coinkite: он обновляется по мере расследования.

  1. Обновите прошивку — и проверьте модель и ветку выпуска. Минимальные исправленные версии, названные в бюллетене Coinkite, — 4.2.0 для Mk2 и Mk3 (последний выпуск для этих моделей), на стандартной ветке 5.6.0 для Mk4 и Mk5 и 1.5.0Q для Q, на ветке Edge — 6.6.0X и 6.6.0QX. Это минимальные версии, а не обязательно текущие рекомендуемые; актуальная таблица — на странице статуса безопасности COLDCARD. Не генерируйте новый сид на затронутой модели, пока не установлено обновление.
  2. Переведите средства на новый сид, сгенерированный на исправленной прошивке. Обновление защищает будущие сиды; усилить уже существующий оно не может. Сид, родившийся с примерно 40 битами, остаётся перебираемым навсегда — выведите его из обращения полностью, никогда не используйте повторно и никогда не отправляйте средства обратно на его адреса. Это касается и кошельков с passphrase: Coinkite советует их владельцам мигрировать как можно скорее. Следуйте официальному руководству по миграции без спешки — проверьте новую резервную копию и адрес получения, отправьте небольшую тестовую транзакцию, затем переведите остальное и храните старую резервную копию, пока миграция не подтверждена.
  3. Никогда не вводите существующую сид-фразу ни на каком сайте, предлагающем «проверить», уязвима ли она. Ввод сида во что угодно онлайн — это ровно то, как забирают оставшиеся средства; сайты-«чекеры» — устойчивый фишинговый шаблон после подобных инцидентов.

Часто задаваемые вопросы

Что такое энтропия кошелька?

Энтропия кошелька — это случайность, используемая при создании сид-фразы. Стандартный сид BIP39 из 12 слов кодирует 128 бит энтропии — 2¹²⁸ возможных сидов. Если генератор предсказуем, реальное число возможных сидов схлопывается, и злоумышленник может перебрать их независимо от того, как сид хранился потом.

Затронут ли мой Coldcard?

Согласно бюллетеню Coinkite, затронуты сиды Mk2 и Mk3, сгенерированные на прошивках от 4.0.1 (март 2021 года) до 4.1.9, а также сиды, сгенерированные на Mk4 и Mk5 до версии 5.6.0 (Edge: 6.6.0X) и на Q до 1.5.0Q (Edge: 6.6.0QX). Сиды, созданные как минимум из 50 честных, независимых, никому не известных бросков кости, не подвержены риску от одной только этой проблемы. Надёжная уникальная passphrase BIP39 добавляет независимый барьер, но слабую passphrase можно подобрать, а сид под ней остаётся слабым, поэтому производитель советует пользователям passphrase тоже мигрировать как можно скорее. Проверьте модель и ветку выпуска на странице статуса безопасности COLDCARD, обновитесь и переведите средства на заново сгенерированный сид.

Можно ли распознать слабый сид, глядя на него?

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

Защищает ли мультиподпись от слабой энтропии?

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

Стоит ли перестать пользоваться аппаратными кошельками?

Нет. Урок уже: сами слова «аппаратный кошелёк» — ещё не гарантия; гарантия — то, как был сгенерирован сид. Продолжайте пользоваться хорошо поддерживаемыми устройствами, устанавливайте обновления прошивки, добавляйте надёжную уникальную passphrase BIP39 там, где она поддерживается, и держите серьёзные балансы за порогом мультиподписи, а не за каким-либо одним сидом.

Если этот инцидент заставил вас пересмотреть собственную схему хранения, структурное решение — перестать оставлять какой-либо один сид в одиночку между вашими средствами и злоумышленником. MultiSig-кошелёк Ownbit ставит порог M-из-N поверх ключей, сгенерированных на независимых устройствах, и каждый из них — стандартная сид-фраза BIP39. Каждый новый пользователь получает 7-дневный бесплатный период, и ваши ключи в любом случае остаются вашими.