Take the 2-minute tour ×
Bitcoin Stack Exchange is a question and answer site for Bitcoin crypto-currency enthusiasts. It's 100% free, no registration required.

The website blockchain.info has an online wallet system MyWallet which creates backups with a .aes.json extension. While I understand it's a json file encrypted with AES using my passphrase, I'm still confused about what am I supposed to do to decrypt it and load it into a local client.

I have OSX 10.6, but for portability sake let's just talk about command line, hoping at least that one stays the same on multiple platforms.

share|improve this question

4 Answers 4

up vote 7 down vote accepted

I wrote a small Python script which can be used to decrypt your encrypted MyWallet. It does the same as the MyWallet JavaScript, only in Python.

Edit: the code below seems to be outdated, here's a working version as of May 2012.

Copy the following into a file, make it executable, then run it:

#!/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))

It will prompt for the wallet backup and one or two passwords, depending on whether the wallet is single or double encrypted. Paste the wallet backup in rather than saving it to a file.

You'll probably need Python 2.x. I've been unable to find a package of the pycrypto stuff for Python 3. Apparently it will be available in the upcoming 'precise' Ubuntu release.

Edit: It seems the backup format has been changed and so this script doesn't work on recent backups.

share|improve this answer
    
Note that my script doesn't convert the private key into 'sipa' format, which is what the official bitcoin client will need (v0.6 onwards) to import a private key. The private keys in the decrypted wallet are in base58 format, but not the 'sipa' format, which includes a checksum. I intend to fix my script to convert private keys to 'sipa' format. –  Chris Moore Feb 29 '12 at 19:07
2  
Now it shows the key in 'sipa' format too. –  Chris Moore Feb 29 '12 at 20:11
    
Both valid answers now, accepting this one both for the effort and because of python. –  Lohoris Mar 27 '12 at 11:05
1  
What, code development in stackexchange comments not good enough for ya? ;) Nice work. –  Chris Moore Apr 30 '12 at 15:55
2  
So gist.github.com/2757171 is the fixed version. –  Chris Moore May 20 '12 at 21:04

I don't know how to do it via the command line, but you can use the tool at

https://blockchain.info/DecryptWallet.html

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

It's basic, but its cross platform and gets the job done. You can also save it offline.

share|improve this answer
    
t can be saved offline, but it includes the javascript blockchain.info/Resources/wallet/bitcoinjs.js so wouldn't that need to be copied locally and DecryptWallet.html edited to be able to access it? –  Stephen Gornick Feb 29 '12 at 4:03
1  
Well, the whole point of this question is being able to restore it offline in case the service collapses, so it is pretty useless to require the service itself to back it up. Sure, saving it offline helps and does the trick, but it's one more file you risk losing, other than your wallet, so it would be better to have standard tools to do that, if possible. –  Lohoris Feb 29 '12 at 8:20
1  
OK, fine. I'll write a short Python script that can do it. –  Chris Moore Feb 29 '12 at 9:51
1  
@Lohoris: You're tempting me to put the javascript in an answer. ;) –  D.H. Feb 29 '12 at 13:13
1  
It turns out that the bitcoinjs.js file was needed for converting the private key to 'sipa' format. That has been inlined into blockchain.info/DecryptWallet.html now, so it is truly now an offline page. –  Chris Moore Feb 29 '12 at 18:27

Piuk has just made a patch to MultiBit that enables blockchain.info 'json' and 'aes.json' files to be imported.

This patch was included in MultiBit 0.3.4. Here is the how-to:

Export wallet from blockchain.info -> Import to MultiBit

1) Do a wallet export from blockchain.info

2) Import into MultiBit using the 'Import private keys' screen.

2.1) In the file chooser you choose the blockchain.info file suffix of ".json" or ".aes.json".

2.2) Choose the blockchain.info export file you want to import.

2.3) Add in either the single password or both passwords if it is double encrypted.

2.4) Press "Import private keys".

Because there are no private key creation dates in the blockchain.info exports I unfortunately have to replay the blocks from the genesis block (this takes a couple of hours) so it is more a "get out of jail" option than something you would use day to day.

share|improve this answer

I took the code from Blockchain.info and converted it into a standalone javascript file that you can run with node.js.

There were some issues as the original code didn't handle wrong passwords, and my code now has a single function check_password(encrypted_json, password) that returns true if it can decrypt it, and false if not.

Now, my goal is to take the above and use it to recover a friend's password. I'll generate a list of all combinations he might have chosen, and test it with this script.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.