Recover ETH private key from kestore file in PHP
Basically in this article I just wanna share my experience that what I have been done the way to recover an eth private keys from keystore files in PHP.
I know we can do easily with the go-ethereum/cmd/ethkey or use web3js.account.recover function. But in my case I need to done this with PHP, need to replicate the way from the easy way (golang/js/python) to be use PHP.
According with the golang, js or python version, it use scrypt
password-base key derivation function (pbkdf) that use AES-128-CTR
method, and still there is no implementation for PHP.
Implementation
And I found php lib PECL :: Package :: scrypt, So need to install it in our machine then enable it first and letst write code.
Read the keystore file
In this article I just share to read and recover single keystore file.
$file = file_get_contents($path);
$json = json_decode($file, true);
Derivate the key
Derivate the key from given password and options that is from parsed keystore file.
$crypto = $json['crypto'];
$derivation = scrypt(
$this->password,
hex2bin($crypto['kdfparams']['salt']),
$crypto['kdfparams']['n'], //The CPU difficulty. Also called "N" in scrypt documentation. Must be a power of 2.
$crypto['kdfparams']['r'], //The memory difficulty. Also called "r" in scrypt documentation.
$crypto['kdfparams']['p'], //The parallel difficulty. Also called "p" in scrypt documentation.
$crypto['kdfparams']['dklen'], //The key length
);
Decrypt the private key
And the last is decrypt the private key from derivation key. In my case the eth keystore version is 3. If the verion is 1 we need to hash the 16 digits from derivation result with keccak.
$key = openssl_decrypt(
hex2bin($crypto['ciphertext']),
strtoupper($crypto['cipher']),
hex2bin($derivation),
OPENSSL_RAW_DATA,
hex2bin($crypto['cipherparams']['iv']),
);
Wrap it up
$file = file_get_contents($path);
$json = json_decode($file, true);
$crypto = $json['crypto'];
$derivation = scrypt(
$this->password,
hex2bin($crypto['kdfparams']['salt']),
$crypto['kdfparams']['n'], //The CPU difficulty. Also called "N" in scrypt documentation. Must be a power of 2.
$crypto['kdfparams']['r'], //The memory difficulty. Also called "r" in scrypt documentation.
$crypto['kdfparams']['p'], //The parallel difficulty. Also called "p" in scrypt documentation.
$crypto['kdfparams']['dklen'], //The key length
);
$key = openssl_decrypt(
hex2bin($crypto['ciphertext']),
strtoupper($crypto['cipher']),
hex2bin($derivation),
OPENSSL_RAW_DATA,
hex2bin($crypto['cipherparams']['iv']),
);
The result from this implementation will have same result with the ethkey
command line tools result.
./ethkey inspect --private <keystore-file>