Recover ETH private key from kestore file in PHP

Ketut Ariasa
2 min readFeb 14, 2022

--

Recover pirvate key from keystore
ethereum recover private key from keystore file

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>

--

--

Ketut Ariasa
Ketut Ariasa

Written by Ketut Ariasa

Code for life, Music for soul, Coffee for heal.

No responses yet