Как восстановить локально резервную копию MyWallet?

На веб-сайте blockchain.info есть система онлайн-кошелька MyWallet , которая создает резервные копии с расширением .aes.json. Хотя я понимаю, что это файл json, зашифрованный с помощью AES с использованием моей парольной фразы, я все еще не понимаю, что мне делать, чтобы расшифровать его и загрузить в локальный клиент.

У меня OSX 10.6, но ради переносимости давайте просто поговорим о командной строке, надеясь, что она хотя бы останется одинаковой на разных платформах.

Ответы (5)

Я написал небольшой скрипт на Python, который можно использовать для расшифровки вашего зашифрованного MyWallet. Он делает то же самое, что и MyWallet JavaScript , только на Python.

Редактировать: приведенный ниже код кажется устаревшим, вот рабочая версия на май 2012 года.

Скопируйте следующее в файл, сделайте его исполняемым, затем запустите:

#!/usr/bin/env python
import base64, hashlib, hmac, json, sys, getpass
from Crypto.Cipher import AES
from Crypto.Hash import RIPEMD, SHA256

base58_chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'

def prompt(p):
    return getpass.getpass(p + ": ")

def decrypt(encrypted, password):
    encrypted = base64.b64decode(encrypted)
    iv, encrypted = encrypted[:16], encrypted[16:]
    length = len(encrypted)
    encrypted += ' ' * (15 - (length-1)%16)
    hash = (hmac.new(password, iv + "\x00\x00\x00\x01", hashlib.sha1).digest() +
            hmac.new(password, iv + "\x00\x00\x00\x02", hashlib.sha1).digest())[:32]
    clear = AES.new(hash, AES.MODE_OFB, iv).decrypt(encrypted)[:length]
    return clear

def base58_decode(v):
  value = 0; ret = ''
  for c in v: value = value*58 + base58_chars.find(c)
  for i in range(32):
      ret = "%c"%(value%256) + ret; value /= 256
  return ret

def base58_encode(v):
    value = 0; ret = ''
    for c in v: value = value*256 + ord(c)
    while value > 0:
        ret = base58_chars[value%58] + ret; value /= 58
    return ret

def to_sipa(s):
    version = 128 # or 239 for testnet
    key = chr(version) + base58_decode(s)
    return base58_encode(key + SHA256.new(SHA256.new(key).digest()).digest()[:4])

clear = decrypt(prompt("encrypted wallet"), prompt("password"))
obj = json.loads(clear)

if (obj.has_key('double_encryption')):
    print("wallet uses double encryption")
    password = obj['sharedKey'].encode('ascii') + prompt("2nd password")
    for key in obj['keys']: key['priv'] = decrypt(key['priv'], password)
for key in obj['keys']: key['priv_sipa'] = to_sipa(key['priv'])
print(json.dumps(obj, indent=4, sort_keys = True))

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

Вам, вероятно, понадобится Python 2.x. Мне не удалось найти пакет материалов pycrypto для Python 3. Очевидно, он будет доступен в предстоящем «точном» выпуске Ubuntu .

Изменить: кажется, что формат резервной копии был изменен, поэтому этот скрипт не работает с последними резервными копиями.

Обратите внимание, что мой сценарий не преобразует закрытый ключ в формат «sipa», который потребуется официальному биткойн-клиенту (начиная с версии 0.6) для импорта закрытого ключа. Закрытые ключи в расшифрованном кошельке имеют формат base58, но не формат «sipa», который включает контрольную сумму. Я намерен исправить свой скрипт для преобразования закрытых ключей в формат «sipa».
Теперь он показывает ключ и в формате 'sipa'.
Теперь оба действительных ответа, принимая этот как за усилия, так и из-за python.
Я добавил ввод кошелька из файла и позволил себе создать для этого проект на битбакете: bitbucket.org/lohoris/mywallet-restore
Что, разработка кода в комментариях stackexchange недостаточно хороша для тебя? ;) Хорошо сделано.
Когда я пробую это в своем резервном кошельке, я получаю «ValueError: объект JSON не может быть декодирован». Я новичок в работе с этой криптобиблиотекой, как бы вы посоветовали мне устранять неполадки?
Я получаю то же самое сейчас. Похоже, формат резервной копии изменился. Беглый взгляд на источник blockchain.info/DecryptWallet.html показывает, что теперь он пробует 4 различных режима шифрования, каждый из которых имеет от 0 до 19 итераций шифрования AES, чего, я думаю, раньше не было.
Этот код дерьмо. В настоящее время используется режим CBC. То, как он проходит итерации, также сбивает с толку (и не в исходном коде ezcrypto AFAICT), поскольку эта опция фактически указывает количество раундов, выполняемых на PBKDF2 при получении ключа из пароля (и это всегда 10 раундов). Вот рабочая версия для последнего формата: gist.github.com/2757146 .
@AndreyFedorov "Суть, которую вы искали, была удалена. Извините за это!"
Итак , gist.github.com/2757171 — это исправленная версия.
Ага, извини за это.
Как я могу легко проверить правильность результата decrypt()? Мой друг потерял пароль от своего кошелька, я хотел бы перебрать множество потенциальных паролей, которые он мог выбрать, пока не найду правильный.
Кажется, для сценария Python требуется Crypto:Cypher, поскольку новичку в Python немного сложно установить его в Windows. Я работаю над этим, просто справедливое предупреждение для новичков.

Я не знаю, как это сделать через командную строку, но вы можете использовать инструмент на

https://blockchain.info/DecryptWallet.html

http://pastehtml.com/view/bprww2t3g.html

Он простой, но кроссплатформенный и выполняет свою работу. Вы также можете сохранить его в автономном режиме.

Его можно сохранить в автономном режиме, но он включает javascript blockchain.info/Resources/wallet/bitcoinjs.js , так что не нужно ли копировать его локально и редактировать DecryptWallet.html, чтобы получить к нему доступ?
Вы можете удалить этот материал (строки 6 и 7), и скрипт все еще будет работать. Такое впечатление, что его оставили случайно. Весь код, необходимый для расшифровки резервной копии, находится в самом файле DecryptWallet.html.
Что ж, весь смысл этого вопроса заключается в возможности восстановить его в автономном режиме в случае сбоя службы, поэтому довольно бесполезно требовать от самой службы резервного копирования. Конечно, сохранение в автономном режиме помогает и делает свое дело, но это еще один файл, который вы рискуете потерять, кроме вашего кошелька, поэтому было бы лучше иметь для этого стандартные инструменты, если это возможно.
Хорошо. Я напишу короткий скрипт на Python, который сможет это сделать.
@Lohoris: Вы ищете несколько простых команд, которые вы можете запомнить? Потому что я не понимаю, как скрипт Python является более «стандартным инструментом», чем Javascript. В любом случае вам придется где-то сохранить этот сценарий или попросить кого-нибудь воспроизвести его для вас.
@DH: он будет заархивирован... здесь ;)
@Lohoris: Вы соблазняете меня добавить javascript в ответ. ;)
@DH: rofl, на самом деле, это сойдет
Оказывается, файл bitcoinjs.js был нужен для преобразования приватного ключа в формат «sipa». Теперь это было встроено в blockchain.info/DecryptWallet.html , так что теперь это действительно автономная страница.
@ChrisMoore: приятно знать!
Смотрите мой ответ - я взял вышеизложенное и преобразовал его в файл javascript, который вы можете запустить с помощью node.js - bitcoin.stackexchange.com/a/7865/78

Piuk только что выпустил патч для MultiBit, который позволяет импортировать файлы blockchain.info «json» и «aes.json».

Этот патч был включен в MultiBit 0.3.4. Вот инструкция:

Экспорт кошелька с blockchain.info -> Импорт в MultiBit

1) Сделайте экспорт кошелька из blockchain.info

2) Импортируйте в MultiBit, используя экран «Импорт закрытых ключей».

2.1) В окне выбора файла вы выбираете суффикс файла blockchain.info «.json» или «.aes.json».

2.2) Выберите файл экспорта blockchain.info, который вы хотите импортировать.

2.3) Добавьте либо один пароль, либо оба пароля, если он зашифрован дважды.

2.4) Нажмите «Импортировать закрытые ключи».

Поскольку в экспорте blockchain.info нет дат создания закрытого ключа, мне, к сожалению, приходится воспроизводить блоки из блока генезиса (это занимает пару часов), так что это скорее вариант «выйти из тюрьмы», чем то, что вы бы использовали. дня в день.

Я взял код с Blockchain.info и преобразовал его в отдельный файл javascript , который можно запускать с помощью node.js.

Были некоторые проблемы, так как исходный код не обрабатывал неправильные пароли, и мой код теперь имеет единственную функцию check_password(encrypted_json, password), которая возвращает true, если он может его расшифровать, и false, если нет.

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

Вот еще одна оболочка, также сделанная в node.js, похожая на ответ выше от ripper234. Этот работает со стандартным вводом, поэтому вы можете использовать внешний инструмент для передачи значений: https://github.com/salibhai1/bitcoin-bruteforce-decrypt