Ethereum Keyfile Handler
eth-keyfile is a Python library for securely handling the encrypted keyfiles used to store Ethereum private keys. It provides functionality to create, load, and decrypt these keyfiles, which conform to the Web3 secret storage standards. The library is currently at version 0.9.1 and maintains a stable release cadence, with ongoing support for modern Python versions (>=3.8, <4). It was previously known as `ethereum-keyfile` and was renamed and moved to the Ethereum foundation GitHub in November 2017.
Warnings
- breaking The library was renamed from `ethereum-keyfile` to `eth-keyfile` in November 2017. The old package `ethereum-keyfile` is no longer maintained and will not receive updates.
- gotcha The `private_key` parameter for `create_keyfile_json` and related functions expects a 32-byte `bytes` object, not a `0x`-prefixed hexadecimal string. Common conversion is needed if your private key is in hex format.
- gotcha Keyfile Version 4 (`version=4`) uses BLS12-381 cryptography and has a more restricted valid range for private keys compared to Version 3 (which uses secp256k1). Randomly generated private keys might not fall within the valid range for V4, leading to errors.
- gotcha Passwords for `create_keyfile_json` and `decode_keyfile_json` should generally be provided as `bytes` objects. Passing plain `str` might lead to unexpected encoding issues or `TypeError` in some environments or Python versions.
- gotcha The security of your Ethereum assets heavily depends on both the strength of the password chosen for the keyfile and the secure storage of the keyfile itself. Losing the password or exposing the keyfile (even encrypted) to unauthorized access can lead to loss of funds.
Install
-
pip install eth-keyfile
Imports
- load_keyfile
from eth_keyfile import load_keyfile
- create_keyfile_json
from eth_keyfile import create_keyfile_json
- decode_keyfile_json
from eth_keyfile import decode_keyfile_json
- extract_key_from_keyfile
from eth_keyfile import extract_key_from_keyfile
Quickstart
import os
import json
from eth_keyfile import create_keyfile_json, decode_keyfile_json
# 1. Generate a new private key (32 bytes)
private_key = os.urandom(32)
password = b"my_secure_password"
# 2. Create a keyfile JSON object (default is V3)
keyfile_json = create_keyfile_json(private_key, password)
# You would typically save this to a file:
# with open('my_keystore.json', 'w') as f:
# json.dump(keyfile_json, f)
print(f"Generated Keyfile (first 50 chars): {json.dumps(keyfile_json)[:50]}...")
# 3. Decode the private key from the keyfile JSON
decoded_private_key = decode_keyfile_json(keyfile_json, password)
assert private_key == decoded_private_key
print(f"Successfully decoded private key: {decoded_private_key.hex()}")
# Example with Keyfile V4 (requires different private key range)
# Note: private_key for v4 must be less than MAX_V4_PRIVATE_KEY
# For simplicity, using a valid v3 key here, but in a real scenario,
# ensure it's valid for bls12-381 curve if using v4.
try:
keyfile_json_v4 = create_keyfile_json(
private_key,
password,
version=4,
description="My V4 Key",
path="m/123/456"
)
print(f"\nGenerated V4 Keyfile (first 50 chars): {json.dumps(keyfile_json_v4)[:50]}...")
decoded_private_key_v4 = decode_keyfile_json(keyfile_json_v4, password)
assert private_key == decoded_private_key_v4
print(f"Successfully decoded V4 private key: {decoded_private_key_v4.hex()}")
except Exception as e:
print(f"\nCould not create V4 keyfile with this private key (expected for some randomly generated keys): {e}")