Skip to content

Instantly share code, notes, and snippets.

@aphexmunky
Forked from anfedorov/mywallet.py
Created March 10, 2013 03:12
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aphexmunky/5126946 to your computer and use it in GitHub Desktop.
Save aphexmunky/5126946 to your computer and use it in GitHub Desktop.
#!/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:]
aeshash = pbkdf2(password, iv, 10, 32)
clear = remove_iso10126_padding(AES.new(aeshash, AES.MODE_CBC, iv).decrypt(encrypted))
return clear
def remove_iso10126_padding(s):
ba = bytearray(s)
pad_len = ba[-1]
return str(ba[:-pad_len])
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])
# pbkdf2 from http://matt.ucc.asn.au/src/pbkdf2.py
from struct import pack
# this is what you want to call.
def pbkdf2( password, salt, itercount, keylen, hashfn = hashlib.sha1 ):
digest_size = hashfn().digest_size
# l - number of output blocks to produce
l = keylen / digest_size
if keylen % digest_size != 0:
l += 1
h = hmac.new( password, None, hashfn )
T = ""
for i in range(1, l+1):
T += pbkdf2_F( h, salt, itercount, i )
return T[0: keylen]
def xorstr( a, b ):
if len(a) != len(b):
raise "xorstr(): lengths differ"
ret = ''
for i in range(len(a)):
ret += chr(ord(a[i]) ^ ord(b[i]))
return ret
def prf( h, data ):
hm = h.copy()
hm.update( data )
return hm.digest()
# Helper as per the spec. h is a hmac which has been created seeded with the
# password, it will be copy()ed and not modified.
def pbkdf2_F( h, salt, itercount, blocknum ):
U = prf( h, salt + pack('>i',blocknum ) )
T = U
for i in range(2, itercount+1):
U = prf( h, U )
T = xorstr( T, U )
return T
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))
@nick1001
Copy link

Did you ever get this to work? I had 2 BTC in my wallet... I'll send ya 0.5 if I can get this cracked! I don't understand where it's specifying where/what the aes.json file is at...

@aphexmunky
Copy link
Author

Hey yeah I did manage to modify it to bruteforce my password based on a set of rules I gave it - looks like I haven't pushed it back though so i'll check my laptop for the changes later.

@ParalysedBeaver
Copy link

Do you still have the version you used to bruteforce your password? I have my wallet.aes.json file, and I'm struggling to remember my password. I registered to blockchain at a time where they didn't send a mnemonic or a passphrase, so I have no recovery options other than bruteforce this file.

@doge2021
Copy link

Did you ever get this to work? I had 2 BTC in my wallet... I'll send ya 0.5 if I can get this cracked! I don't understand where it's specifying where/what the aes.json file is at...
you may reach BTC recover , there is a chance to recover it.

@doge2021
Copy link

Do you still have the version you used to bruteforce your password? I have my wallet.aes.json file, and I'm struggling to remember my password. I registered to blockchain at a time where they didn't send a mnemonic or a passphrase, so I have no recovery options other than bruteforce this file.

you may reach BTC recover , there is a chance to recover it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment