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:
import base64, hashlib, hmac, json, sys, getpass
from Crypto.Cipher import AES
from Crypto.Hash import RIPEMD, SHA256
base58_chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
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]
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
value = 0; ret = ''
for c in v: value = value*256 + ord(c)
while value > 0:
ret = base58_chars[value%58] + ret; value /= 58
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)
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.