def test_key_store_can_persist_key_files(tmp_path, sample_bls_key_pairs, has_key_pairs): some_password = b"password" public_key, private_key = tuple(sample_bls_key_pairs.items())[0] private_key_bytes = private_key.to_bytes(32, "little") encoded_private_key = private_key_bytes.hex() if has_key_pairs: key_pairs = sample_bls_key_pairs else: key_pairs = {} key_store = KeyStore( key_pairs=key_pairs, key_store_dir=tmp_path, password_provider=lambda _public_key: some_password, ) with key_store.persistence(): assert not tuple(key_store._key_store_dir.iterdir()) key_store.import_private_key(encoded_private_key) key_files = tuple(key_store._key_store_dir.iterdir()) assert len(key_files) == 1 key_file = key_files[0] with open(key_file) as key_file_handle: key_file_json = json.load(key_file_handle) assert decode_hex(key_file_json["public_key"]) == public_key assert private_key_bytes == eth_keyfile.decode_keyfile_json( key_file_json, some_password)
def unlock(self, password: str): if self.unlocked: return self.private_key = encode_hex( decode_keyfile_json(self.keyfile_content, password.encode())) if self.token is not None: self.token.privkey = self.private_key
def decode_keystore_from_json(cls, keystore, password): """ TODO 解码Keystore Json格式数据 :param keystore: keystore 文件 json 数据, 类型为 dict :param password: 交易密码, 对keystore进行解密(对称加密算法) :return: """ if not isinstance(keystore, dict): raise EtherError({"err": u"Keystore Json 格式错误!", "code": 4000}) try: hex_pri = decode_keyfile_json(keystore, bytes(password, encoding='utf8')) pri_key = PrivateKey.from_bytes(hex_pri) return EtherCommon(_pri=pri_key, _pub=pri_key.public_key) except Exception as e: if str(e) == "MAC mismatch": raise EtherError({"err": u"交易密码错误!", "code": 4001}) else: raise EtherError({ "err": u"keystore解码异常!", "exception": str(e), "code": 5000 })
def wallet_from_keystore(keystore: dict, password: str = "", testnet: bool = False): "Recover Binance wallet from keystore" private_key = decode_keyfile_json(keystore, password=encoding.to_bytes(password)) key = keys.HDKey(private_key) return Wallet(key=key, testnet=testnet)
def decrypt(keyfile_json, password): if isinstance(keyfile_json, str): keyfile = json.loads(keyfile_json) elif is_dict(keyfile_json): keyfile = keyfile_json else: raise TypeError("The keyfile should be supplied as a JSON string, or a dictionary.") password_bytes = text_if_str(to_bytes, password) return decode_keyfile_json(keyfile, password_bytes)
def decrypt(keyfile_json, password): if isinstance(keyfile_json, str) or ( sys.version_info.major < 3 and isinstance(keyfile_json, unicode)): # noqa: 821 keyfile = json.loads(keyfile_json) elif is_dict(keyfile_json): keyfile = keyfile_json else: raise TypeError("The keyfile should be supplied as a JSON string, or a dictionary.") password_bytes = text_if_str(to_bytes, password) return decode_keyfile_json(keyfile, password_bytes)
def get_private_key(keystorePtah, password): """ 获取私钥 :param keystorePtah: keystore钱包json文件路径 :param password: 钱包密码 :return:钱包私钥 """ privateKey = eth_keyfile.decode_keyfile_json(json.load(open(keystorePtah)), password) return privateKey.hex()
def ReadKeysFromFile(filename, password=None): out = dict() with open(filename) as f: #Read File file_json = json.load(f) #Extract Address addr = bytes_from_hex_string(file_json['stealth_address'], 65) out['stealth_address'] = addr out['pub_scan_key'], out['pub_spend_key'] = GetKeysFromStealthAddress(addr) #Extract Scan Key if password==None: password = getpass() out['scan_key'] = decode_keyfile_json(file_json['scan_key'], bytes(password, 'utf')) out['spend_key'] = decode_keyfile_json(file_json['scan_key'], bytes(password, 'utf')) del password return out
def decrypt(keyfile_json, password): if isinstance(keyfile_json, str): keyfile = json.loads(keyfile_json) elif is_dict(keyfile_json): keyfile = keyfile_json else: raise TypeError( "The keyfile should be supplied as a JSON string, or a dictionary." ) password_bytes = text_if_str(to_bytes, password) return decode_keyfile_json(keyfile, password_bytes)
def transfer_value(self, password, to_address, value, fee=10000000000000000, uri='https://testwallet.icon.foundation/api/', hex_private_key=None, **kwargs): """ transfer the specific value with private key :param password: Password including alphabet character, number, and special character. :param to_address: Address of wallet to receive the asset. :param value: Amount of money. :param fee: Transaction fee. :param uri: Api url. type(str) :param hex_private_key: the private key with a hexadecimal number :return: response """ try: uri = f'{uri}v2' byte_private_key = decode_keyfile_json(self.wallet_info, bytes(password, 'utf-8')) validate_address(to_address) validate_address(self.address) validate_address_is_not_same(to_address, self.address) method = 'icx_sendTransaction' value, fee = int(value), int(fee) check_amount_and_fee_is_valid(value, fee) params = make_params(self.address, to_address, value, fee, method, byte_private_key) payload = create_jsonrpc_request_content(0, method, params) # Request the balance repeatedly until we get the response from ICON network. request_gen = request_generator(uri) balance = get_balance_after_transfer(self.address, uri, request_gen) check_balance_enough(balance, value, fee) next(request_gen) response = request_gen.send(payload) return response except FileNotFoundError: raise FilePathIsWrong except IsADirectoryError: raise FilePathIsWrong except ValueError: raise PasswordIsWrong
def get_private_key(key_path: Path, password_path: Optional[Path] = None) -> Optional[str]: """Open a JSON-encoded private key and return it If a password file is provided, uses it to decrypt the key. If not, the password is asked interactively. Raw hex-encoded private keys are supported, but deprecated.""" if not key_path: log.fatal(f"key_path has to be something but got {key_path}") return None if not os.path.exists(key_path): log.fatal("%s: no such file", key_path) return None if not check_permission_safety(key_path): log.fatal("Private key file %s must be readable only by its owner.", key_path) return None if password_path and not check_permission_safety(password_path): log.fatal("Password file %s must be readable only by its owner.", password_path) return None with open(key_path) as keyfile: private_key = keyfile.readline().strip() if is_hex(private_key) and len(decode_hex(private_key)) == 32: log.warning( "Private key in raw format. Consider switching to JSON-encoded" ) else: keyfile.seek(0) try: json_data = json.load(keyfile) if password_path: with open(password_path) as password_file: password = password_file.readline().strip() else: password = getpass.getpass( "Enter the private key password: "******"crypto"]["kdf"] == "pbkdf2": password = password.encode() # type: ignore private_key = encode_hex( decode_keyfile_json(json_data, password)) except ValueError: log.fatal("Invalid private key format or password!") return None return private_key
def _load_key_file(self, key_file: Path) -> Tuple[BLSPubkey, BLSPrivateKey, str]: with open(key_file) as key_file_handle: keyfile_json = json.load(key_file_handle) public_key = BLSPubkey(decode_hex(keyfile_json["public_key"])) password = self._password_provider(public_key) try: private_key = eth_keyfile.decode_keyfile_json(keyfile_json, password) except ValueError: self.logger.error( "password was incorrect for public key %s", encode_hex(public_key) ) raise return (public_key, private_key, keyfile_json["id"])
def unlock(self, password: str): """Unlock the account with a password. If the account is already unlocked, nothing happens, even if the password is wrong. Raises: ValueError: (originating in ethereum.keys) if the password is wrong (and the account is locked) """ if self.locked: self._privkey = decode_keyfile_json(self.keystore, password.encode('UTF-8')) self.locked = False self.address # get address such that it stays accessible after a subsequent lock
def unlock(self, password: bytes): """ Unlock the account with a password. If the account is already unlocked, nothing happens, even if the password is wrong. :raises: :exc:`ValueError` (originating in ethereum.keys) if the password is wrong (and the account is locked) """ if self.locked: password = to_string(password) self._privkey = decode_keyfile_json(self.keystore, password) self.locked = False # get address such that it stays accessible after a subsequent lock self.address
def _load_key_file(self, key_file: Path) -> KeyPair: with open(key_file) as key_file_handle: keyfile_json = json.load(key_file_handle) public_key = decode_hex(keyfile_json["public_key"]) if not self._demo_mode: self.logger.warn( "please enter password for protected keyfile with public key %s:", humanize_bytes(public_key), ) password = getpass.getpass().encode() else: password = EMPTY_PASSWORD private_key = eth_keyfile.decode_keyfile_json( keyfile_json, password) return _compute_key_pair_from_private_key_bytes(private_key)
def load_from_keystore(path, password): """ Load an account from a Keystore/JSON file :param path: the path to the keystore :param password: the password to decrypt the keystore :return: the account raise an error if the account cannot be opened """ with open(path, 'r') as fp: j = json.load(fp) raw_priv = keystore.decode_keyfile_json(j, password.encode("utf-8")) signing_key = SigningKey(seed=raw_priv[0:32], encoder=RawEncoder) kp = Account(signing_key, signing_key.verify_key) return kp
def decrypt(keystore: dict, password: bytes) -> bytes: ''' Decrypt a keystore into a private key (bytes). Parameters ---------- keystore : dict A keystore. password : bytes A password. Returns ------- bytes A private key in bytes. ''' return eth_keyfile.decode_keyfile_json(keystore, password)
def eth_sign_with_keyfile(message: bytes, raw: bool, keyfile: str, password: str): assert(isinstance(message, bytes)) assert(isinstance(raw, bool)) assert(isinstance(keyfile, str)) assert(isinstance(password, str)) if not raw: message = hexstring_to_bytes(Eth._recoveryMessageHash(data=message)) key = eth_keyfile.decode_keyfile_json(eth_keyfile.load_keyfile(keyfile), bytes(password, 'utf-8')) pk = PrivateKey(key, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(message, raw=True) ) signature = signature[0] + utils.bytearray_to_bytestr([signature[1]]) signature_hex = signature.hex()[0:128] + int_to_bytes(ord(bytes.fromhex(signature.hex()[128:130]))+27).hex() return '0x' + signature_hex
def decrypt(keyfile_json, password): """ Decrypts a private key that was encrypted using an Ethereum client or :meth:`~Account.encrypt`. :param keyfile_json: The encrypted key :type keyfile_json: dict or str :param str password: The password that was used to encrypt the key :returns: the raw private key :rtype: ~hexbytes.main.HexBytes .. code-block:: python >>> encrypted = { 'address': '5ce9454909639d2d17a3f753ce7d93fa0b9ab12e', 'crypto': {'cipher': 'aes-128-ctr', 'cipherparams': {'iv': '78f214584844e0b241b433d7c3bb8d5f'}, 'ciphertext': 'd6dbb56e4f54ba6db2e8dc14df17cb7352fdce03681dd3f90ce4b6c1d5af2c4f', 'kdf': 'pbkdf2', 'kdfparams': {'c': 1000000, 'dklen': 32, 'prf': 'hmac-sha256', 'salt': '45cf943b4de2c05c2c440ef96af914a2'}, 'mac': 'f5e1af09df5ded25c96fcf075ada313fb6f79735a914adc8cb02e8ddee7813c3'}, 'id': 'b812f3f9-78cc-462a-9e89-74418aa27cb0', 'version': 3} >>> import getpass >>> Account.decrypt(encrypted, getpass.getpass()) HexBytes('0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364') """ if isinstance(keyfile_json, str): keyfile = json.loads(keyfile_json) elif is_dict(keyfile_json): keyfile = keyfile_json else: raise TypeError( "The keyfile should be supplied as a JSON string, or a dictionary." ) password_bytes = text_if_str(to_bytes, password) return HexBytes(decode_keyfile_json(keyfile, password_bytes))
def decrypt(keyfile_json, password): """ Decrypts a private key that was encrypted using an Ethereum client or :meth:`~Account.encrypt`. :param keyfile_json: The encrypted key :type keyfile_json: dict or str :param str password: The password that was used to encrypt the key :returns: the raw private key :rtype: ~hexbytes.main.HexBytes .. doctest:: python >>> encrypted = { ... 'address': '5ce9454909639d2d17a3f753ce7d93fa0b9ab12e', ... 'crypto': {'cipher': 'aes-128-ctr', ... 'cipherparams': {'iv': '482ef54775b0cc59f25717711286f5c8'}, ... 'ciphertext': 'cb636716a9fd46adbb31832d964df2082536edd5399a3393327dc89b0193a2be', ... 'kdf': 'scrypt', ... 'kdfparams': {}, ... 'kdfparams': {'dklen': 32, ... 'n': 262144, ... 'p': 8, ... 'r': 1, ... 'salt': 'd3c9a9945000fcb6c9df0f854266d573'}, ... 'mac': '4f626ec5e7fea391b2229348a65bfef532c2a4e8372c0a6a814505a350a7689d'}, ... 'id': 'b812f3f9-78cc-462a-9e89-74418aa27cb0', ... 'version': 3} >>> Account.decrypt(encrypted, 'password') HexBytes('0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364') """ if isinstance(keyfile_json, str): keyfile = json.loads(keyfile_json) elif is_dict(keyfile_json): keyfile = keyfile_json else: raise TypeError( "The keyfile should be supplied as a JSON string, or a dictionary." ) password_bytes = text_if_str(to_bytes, password) return HexBytes(decode_keyfile_json(keyfile, password_bytes))
def load(file_path, password): """Loads a wallet from a key store file with your password and generates an instance of Wallet. :param file_path: File path of the key store file. type(str) :param password: Password for the key store file. It must include alphabet character, number, and special character. :return: An instance of Wallet class. """ if not is_password_of_keystore_file(password): raise KeyStoreException('Invalid password.') try: keystore = load_keyfile(file_path) if is_keystore_file(keystore): bytes_private_key = decode_keyfile_json(keystore, bytes(password, 'utf-8')) private_key_object = PrivateKey(bytes_private_key) wallet = KeyWallet(private_key_object) return wallet except FileNotFoundError: raise KeyStoreException("File is not found.") except ValueError: raise KeyStoreException("Password is wrong.")
def test_key_store_can_persist_key_files(tmp_path, sample_bls_key_pair): config = Config( key_store_constructor=lambda config: KeyStore.from_config(config), root_data_dir=tmp_path, ) some_password = b"password" public_key, private_key = sample_bls_key_pair private_key_bytes = private_key.to_bytes(length=32, byteorder="big") encoded_private_key = private_key_bytes.hex() with config.key_store as key_store: assert not tuple(key_store._location.iterdir()) key_store.import_private_key(encoded_private_key, some_password) key_files = tuple(key_store._location.iterdir()) assert len(key_files) == 1 key_file = key_files[0] with open(key_file) as key_file_handle: key_file_json = json.load(key_file_handle) assert decode_hex(key_file_json["public_key"]) == public_key assert private_key_bytes == eth_keyfile.decode_keyfile_json( key_file_json, some_password)
def reclaim_eth(account: Account, chain_rpc_urls: dict, data_path: str, min_age_hours: int): web3s: Dict[str, Web3] = { name: Web3(HTTPProvider(urls[0])) for name, urls in chain_rpc_urls.items() } data_path = Path(data_path) log.info('Starting eth reclaim', data_path=data_path) addresses = dict() for node_dir in data_path.glob('**/node_???'): scenario_name: Path = node_dir.parent.name last_run = next( iter( sorted( list(node_dir.glob('run-*.log')), key=lambda p: p.stat().st_mtime, reverse=True, ), ), None, ) # If there is no last run assume we can reclaim if last_run: age_hours = (time.time() - last_run.stat().st_mtime) / 3600 if age_hours < min_age_hours: log.debug( 'Skipping too recent node', scenario_name=scenario_name, node=node_dir.name, age_hours=age_hours, ) continue for keyfile in node_dir.glob('keys/*'): keyfile_content = json.loads(keyfile.read_text()) address = keyfile_content.get('address') if address: addresses[to_checksum_address(address)] = decode_keyfile_json(keyfile_content, b'') log.info('Reclaiming candidates', addresses=list(addresses.keys())) txs = defaultdict(list) reclaim_amount = defaultdict(int) for chain_name, web3 in web3s.items(): log.info('Checking chain', chain=chain_name) for address, privkey in addresses.items(): balance = web3.eth.getBalance(address) if balance > RECLAIM_MIN_BALANCE: drain_amount = balance - (web3.eth.gasPrice * VALUE_TX_GAS_COST) log.info( 'Reclaiming', from_address=address, amount=drain_amount.__format__(',d'), chain=chain_name, ) reclaim_amount[chain_name] += drain_amount client = JSONRPCClient(web3, privkey) txs[chain_name].append( client.send_transaction( to=account.address, value=drain_amount, startgas=VALUE_TX_GAS_COST, ), ) for chain_name, chain_txs in txs.items(): wait_for_txs(web3s[chain_name], chain_txs, 1000) for chain_name, amount in reclaim_amount.items(): log.info('Reclaimed', chain=chain_name, amount=amount.__format__(',d'))
def check_passphrase(self, passphrase): try: decode_keyfile_json(self.content, passphrase.encode()) return True except Exception: return False
def private_key(self): if not self.passphrase: raise ValueError( "Passphrase is not known, can not get private key") return decode_keyfile_json(self.content, self.passphrase.encode())
def load(filename, password): with open(filename) as wallet: privkey = eth_keyfile.decode_keyfile_json(json.load(wallet), password.encode("utf-8")) return Wallet(privkey)
def reclaim_eth( account: Account, chain_rpc_urls: dict, data_path: pathlib.Path, min_age_hours: int ): web3s: Dict[str, Web3] = { name: Web3(HTTPProvider(urls[0])) for name, urls in chain_rpc_urls.items() } log.info("Starting eth reclaim", data_path=data_path) addresses = dict() for node_dir in data_path.glob("**/node_???"): scenario_name: Path = node_dir.parent.name last_run = next( iter( sorted( list(node_dir.glob("run-*.log")), key=lambda p: p.stat().st_mtime, reverse=True ) ), None, ) # If there is no last run assume we can reclaim if last_run: age_hours = (time.time() - last_run.stat().st_mtime) / 3600 if age_hours < min_age_hours: log.debug( "Skipping too recent node", scenario_name=scenario_name, node=node_dir.name, age_hours=age_hours, ) continue for keyfile in node_dir.glob("keys/*"): keyfile_content = json.loads(keyfile.read_text()) address = keyfile_content.get("address") if address: addresses[to_checksum_address(address)] = decode_keyfile_json(keyfile_content, b"") log.info("Reclaiming candidates", addresses=list(addresses.keys())) txs = defaultdict(set) reclaim_amount = defaultdict(int) for chain_name, web3 in web3s.items(): log.info("Checking chain", chain=chain_name) for address, privkey in addresses.items(): balance = web3.eth.getBalance(address) if balance > RECLAIM_MIN_BALANCE: drain_amount = balance - (web3.eth.gasPrice * VALUE_TX_GAS_COST) log.info( "Reclaiming", from_address=address, amount=drain_amount.__format__(",d"), chain=chain_name, ) reclaim_amount[chain_name] += drain_amount client = JSONRPCClient(web3, privkey) txs[chain_name].add( client.send_transaction( to=account.address, value=drain_amount, startgas=VALUE_TX_GAS_COST ) ) for chain_name, chain_txs in txs.items(): wait_for_txs(web3s[chain_name], chain_txs, 1000) for chain_name, amount in reclaim_amount.items(): log.info("Reclaimed", chain=chain_name, amount=amount.__format__(",d"))
def _load_eth_key(path: str, password: str) -> (str, bytes): keyfile_data = load_keyfile(path) pkey = decode_keyfile_json(keyfile_data, password) return keyfile_data.get('address'), pkey
def privkey(self): return decode_keyfile_json(self.keyfile_content, b"")
from eth_keyfile import load_keyfile, decode_keyfile_json directory = "C:/Users/alegr/OneDrive/Documents/GitHub/ethereum/StealthAddresses/py/" keystore_file = "Keystore--975fbcbaeb9b3852b096ec0242aa2d96400406af.json" address = 0x975fbcbaeb9b3852b096ec0242aa2d96400406af tokens = 70000000000000000 nonce = 1 tx_data = address.to_bytes(20, 'big') tx_data += tokens.to_bytes(32, 'big') tx_data += nonce.to_bytes(32, 'big') message = keccak_256(tx_data).digest() #Import Scan and Spend Key password = getpass() priv_key = decode_keyfile_json(load_keyfile(directory + keystore_file), bytes(password, 'utf')) #Create Signature from py_ecc import secp256k1 sig = secp256k1.ecdsa_raw_sign(message, priv_key) print("data:") print(hex(int.from_bytes(tx_data, 'big'))) print() print("sig:") print(sig[0]) print(hex(sig[1])) print(hex(sig[2]))
def decode_keyfile_json(raw_keyfile_json, password): if not is_string(password): password = to_string(password) return eth_keyfile.decode_keyfile_json(raw_keyfile_json, password)