Как биткойн-клиент шифрует файл wallet.dat?

Какой алгоритм используется для шифрования файла wallet.dat?

Ответы (2)

Подробное объяснение можно найти в README приложения: https://github.com/bitcoin/bitcoin/blob/6b8a5ab622e5c9386c872036646bf94da983b190/doc/README .

Короче говоря:

  • Парольная фраза преобразуется в пару ключ/iv с использованием EVP с динамическим количеством раундов.
  • Эта пара ключ/iv используется для шифрования случайно сгенерированного главного ключа с использованием AES-256-CBC.
  • Секретная часть ключей кошелька затем шифруется с использованием этого мастер-ключа, опять же с помощью AES-256-CBC.
Хм, кажется, README время от времени обновляется, и описания шифрования кошелька больше нет. Это та версия, на которую вы ссылались? github.com/bitcoin/bitcoin/blob/…
@ThePiachu Спасибо за обновленную ссылку, она сэкономила мне несколько минут. Я обновил ответ, чтобы отразить постоянную ссылку.

Ответ Питера охватывает технические детали, поэтому я не буду повторяться. Я бы добавил, что пользователи должны помнить, что самое слабое место в кошельке с биткойн-ядром или любой криптографически сильной системе шифрования — это парольная фраза. Система преобразует парольную фразу в ключ AES-256, и этот ключ, полученный из пароля, используется для шифрования случайно сгенерированного главного ключа кошелька. Главный ключ кошелька не может быть взломан методом грубой силы, за исключением скомпрометированного или ошибочного PRNG, однако злоумышленники могут попытаться взломать саму парольную фразу.

Клиент добавляет попытки защититься от этой атаки, используя как соль (случайное число), так и несколько раундов хеширования. Соль предотвращает атаку предварительного вычисления, поскольку одна и та же фраза-пароль с разными солями будет давать разные ключи. Использование нескольких раундов хеширования замедляет атаки грубой силы, потому что злоумышленнику также потребуется выполнить несколько раундов для каждой попытки ввода парольной фразы.

Клиент использует динамическую защиту ключей. Это означает, что количество раундов варьируется в зависимости от вычислительной мощности клиента (чтобы время шифрования или дешифрования оставалось менее 1 секунды). Чем больше вычислительной мощности у вашего оборудования, тем больше раундов оно выполняет и тем сложнее будет взломать пароль. Когда вы меняете свою парольную фразу, клиент регулирует количество динамических раундов в зависимости от вычислительной мощности вашего текущего оборудования. Периодически обновляя свой пароль, вы можете гарантировать, что ключ, полученный из пароля, соответствует закону Мура.

Закалка ключей с помощью соли и растяжения ключей не может зайти так далеко. Если ваш пароль "p@ssw0rd!" или какой-либо другой известный часто используемый пароль, перебор кошелька все равно будет тривиальным. Чтобы проиллюстрировать, почему, давайте предположим, что у злоумышленника есть оборудование, которое может выполнять 100 млн хэшей в секунду, а ваш кошелек использует 100 000 раундов хеширования. Это означает, что аппаратное обеспечение злоумышленников (100 миллионов хэшей) может пытаться ввести 1000 паролей в секунду. Таким образом, кошелек замедляет злоумышленника, но если пароль слабый, он не может достаточно замедлить его. В открытом доступе есть списки ранее скомпрометированных/украденных/взломанных паролей с десятками миллионов паролей. Без расширения ключа злоумышленник может попытаться ввести все возможные известные пароли менее чем за секунду. Растяжка клавиш замедляет это до нескольких часов. С другой стороны, предположим, что ваш пароль был неизвестен и достаточно надежен, чтобы с помощью одного хэша в среднем потребовался один день для грубой силы. С 100 000 выстрелов, что увеличивает время до столетий.

Я бы добавил, что парольная фраза называется парольной фразой не просто так. Использование «Это очень длинная, но очень простая парольная фраза для запоминания» на тонны порядков безопаснее, чем «fl@a%%zG», даже при использовании атаки по словарю.
@AndreasBonini: благодаря вашему комментарию эта конкретная фраза-пароль теперь будет частью словаря ;-)