#!/usr/bin/env python # Bitcoin wallet keys AES encryption / decryption (see http://github.com/joric/pywallet) # Uses pycrypto or libssl or libeay32.dll or aes.py from http://code.google.com/p/slowaes crypter = None try: from Crypto.Cipher import AES crypter = 'pycrypto' except: pass class Crypter_pycrypto( object ): def SetKeyFromPassphrase(self, vKeyData, vSalt, nDerivIterations, nDerivationMethod): data = vKeyData + vSalt for i in range(nDerivIterations): data = hashlib.sha512(data).digest() self.SetKey(data[0:32]) self.SetIV(data[32:32+16]) return len(data) def SetKey(self, key): self.chKey = key def SetIV(self, iv): self.chIV = iv[0:16] def Encrypt(self, data): return AES.new(self.chKey,AES.MODE_CBC,self.chIV).encrypt(data)[0:32] def Decrypt(self, data): return AES.new(self.chKey,AES.MODE_CBC,self.chIV).decrypt(data)[0:32] try: if not crypter: import ctypes import ctypes.util ssl = ctypes.cdll.LoadLibrary (ctypes.util.find_library ('ssl') or 'libeay32') crypter = 'ssl' except: pass class Crypter_ssl(object): def __init__(self): self.chKey = ctypes.create_string_buffer (32) self.chIV = ctypes.create_string_buffer (16) def SetKeyFromPassphrase(self, vKeyData, vSalt, nDerivIterations, nDerivationMethod): strKeyData = ctypes.create_string_buffer (vKeyData) chSalt = ctypes.create_string_buffer (vSalt) return ssl.EVP_BytesToKey(ssl.EVP_aes_256_cbc(), ssl.EVP_sha512(), chSalt, strKeyData, len(vKeyData), nDerivIterations, ctypes.byref(self.chKey), ctypes.byref(self.chIV)) def SetKey(self, key): self.chKey = ctypes.create_string_buffer(key) def SetIV(self, iv): self.chIV = ctypes.create_string_buffer(iv) def Encrypt(self, data): buf = ctypes.create_string_buffer(len(data) + 16) written = ctypes.c_int(0) final = ctypes.c_int(0) ctx = ssl.EVP_CIPHER_CTX_new() ssl.EVP_CIPHER_CTX_init(ctx) ssl.EVP_EncryptInit_ex(ctx, ssl.EVP_aes_256_cbc(), None, self.chKey, self.chIV) ssl.EVP_EncryptUpdate(ctx, buf, ctypes.byref(written), data, len(data)) output = buf.raw[:written.value] ssl.EVP_EncryptFinal_ex(ctx, buf, ctypes.byref(final)) output += buf.raw[:final.value] return output def Decrypt(self, data): buf = ctypes.create_string_buffer(len(data) + 16) written = ctypes.c_int(0) final = ctypes.c_int(0) ctx = ssl.EVP_CIPHER_CTX_new() ssl.EVP_CIPHER_CTX_init(ctx) ssl.EVP_DecryptInit_ex(ctx, ssl.EVP_aes_256_cbc(), None, self.chKey, self.chIV) ssl.EVP_DecryptUpdate(ctx, buf, ctypes.byref(written), data, len(data)) output = buf.raw[:written.value] ssl.EVP_DecryptFinal_ex(ctx, buf, ctypes.byref(final)) output += buf.raw[:final.value] return output try: if not crypter: from aes import * crypter = 'pure' except: pass class Crypter_pure(object): def __init__(self): self.m = AESModeOfOperation() self.cbc = self.m.modeOfOperation["CBC"] self.sz = self.m.aes.keySize["SIZE_256"] def SetKeyFromPassphrase(self, vKeyData, vSalt, nDerivIterations, nDerivationMethod): data = vKeyData + vSalt for i in range(nDerivIterations): data = hashlib.sha512(data).digest() self.SetKey(data[0:32]) self.SetIV(data[32:32+16]) return len(data) def SetKey(self, key): self.chKey = [ord(i) for i in key] def SetIV(self, iv): self.chIV = [ord(i) for i in iv] def Encrypt(self, data): mode, size, cypher = self.m.encrypt(data, self.cbc, self.chKey, self.sz, self.chIV) return ''.join(map(chr, cypher)) def Decrypt(self, data): chData = [ord(i) for i in data] return self.m.decrypt(chData, self.sz, self.cbc, self.chKey, self.sz, self.chIV) import hashlib def Hash(data): return hashlib.sha256(hashlib.sha256(data).digest()).digest() def main(): #address addr = '1AJ3vE2NNYW2Jzv3fLwyjKF1LYbZ65Ez64' sec = '5JMhGPWc3pkdgPd9jqVZkRtEp3QB3Ze8ihv62TmmvzABmkNzBHw' secret = '47510706d76bc74a5d57bdcffc68c9bbbc2d496bef87c91de7f616129ac62b5f'.decode('hex') pubkey = '046211d9b7836892c8eef49c4d0cad7797815eff95108e1d30745c03577596c9c00d2cb1ab27c7f95c28771278f89b7ff40da49fe9b4ee834a3f6a88324db837d8'.decode('hex') ckey = '0f8c75e4c6ab3c642dd06786af80ca3a93e391637d029f1da919dad77d3c8e477efd479814ddf4c459aeba042420868f'.decode('hex') #master key crypted_key = '1e1d7ab34d8007f214eb528a1007c6721b9cd1d2c257adb25378ea8e47e3bdd22cfe93a8b6f18dcbe4206fe8c8178ff1'.decode('hex') salt = '3f94e3c670b695dd'.decode('hex') rounds = 47135 method = 0 password = '12345' global crypter if crypter == 'pycrypto': crypter = Crypter_pycrypto() elif crypter == 'ssl': crypter = Crypter_ssl() print "using ssl" elif crypter == 'pure': crypter = Crypter_pure() print "using slowaes" else: print("Need pycrypto of libssl or libeay32.dll or http://code.google.com/p/slowaes") exit(1) crypter.SetKeyFromPassphrase(password, salt, rounds, method) masterkey = crypter.Decrypt(crypted_key) crypter.SetKey(masterkey) crypter.SetIV(Hash(pubkey)) d = crypter.Decrypt(ckey) e = crypter.Encrypt(d) print "masterkey:", masterkey.encode('hex') print 'c:', ckey.encode('hex') print 'd:', d.encode('hex') print 'e:', e.encode('hex') if __name__ == '__main__': main()