I use the Mist wallet.
I would like to know:
- How I can get the private key of my account.
- How I can use this private key to sign messages.
Ethereum Stack Exchange is a question and answer site for users of Ethereum, the decentralized application platform and smart contract enabled blockchain. It only takes a minute to sign up.
Sign up to join this communityI use the Mist wallet.
I would like to know:
You can use MyEtherWallet or MyCrypto(fork of MyEtherWallet) offline only wallet "view wallet details" function to extract private key from wallet json file. Feel free to use its offline version on an air gapped computer to secure your private key.
Edit: MyCrypto only provides this function in the offline version of the wallet now for obvious security issues of getting a private key from an internet site on a connected computer. So you are warned that you should only do that on an air-gaped computer.
If you have node.js, you can do this in node
var keyth=require('keythereum')
//install keythereum by runing "npm install keythereum"
var keyobj=keyth.importFromFile('0x...your..ether..address..','./Appdata/roaming/ethereum')
'./Appdata/roaming/ethereum' is the folder contains 'keystore'. importFile looks for 'keystore' in that folder.
var privateKey=keyth.recover('your_password',keyobj) //this takes a few seconds to finish
privateKey.toString('hex')
aes-128-ctr is not available
: github.com/ethereumjs/keythereum/issues/73
I will try to provide an alternative solution that is more "hands-on" than using a particular application, or JavaScript. It seems to me lacking "hands-on" details might be one of the reasons why similar questions keep spawning up (and ultimately get voted close and redirected to here -- see the list of linked questions).
The steps here are heavily influenced by answers to this question.
Given
output:
with steps
We will mainly use unix/linux shell and python3 (>3.6 for the scrypt support) for easier Keccak and scrypt.
To make the steps easy to reproduce, we create a test private key whose value is "1" (don't do it in production)
# create a temp work directory
cd $(mktemp -d)
echo "0000000000000000000000000000000000000000000000000000000000000001" > plain_key.txt
geth --datadir . account import plain_key.txt
Geth will ask for new password. Input a simple "a" (don't do in production), which will be used later in decryption.
Geth should output
Address: {7e5f4552091a69125d5dfcb7b8c2659029395bdf}
which, interestingly, often receives funds. Geth should have also created a file under ./keystore/UTC-<< timestamp >>-7e5f4552091a69125d5dfcb7b8c2659029395bdf:
$ cat keystore/UTC*
{
"address":"7e5f4552091a69125d5dfcb7b8c2659029395bdf",
"crypto":{
"cipher":"aes-128-ctr",
"ciphertext":"f97975cb858242372a7c910de23976be4f545ad6b4d6ddb86e54b7d9b3b1c6a1",
"cipherparams":{
"iv":"7fa01f1d0d6a7117382632028cb0c323"
},
"kdf":"scrypt",
"kdfparams":{
"dklen":32,
"n":262144,
"p":1,
"r":8,
"salt":"859c5d345ee58dfca293950c540016af3a889d0dacb00b8eff2ac2b150f0b07e"
},
"mac":"31ccb67e48aba5d64bf727a5c6589fd5857021540d25d12df31323f10ae2bf97"
},
"id":"dc74bc44-784b-4293-b1c7-b91e9fd7d6cc",
"version":3
}
(note: the above output has been formatted for better display) The test setup is now complete. Next, we decrypt the private key with the known password "a", and compare the result with the expected value "1".
As explained in answers to this question here,
In our example, the key derivation function is scrypt. We use Python3 to do the decryption.
python3
>>> import hashlib
>>> dec_key = hashlib.scrypt(bytes('a', 'utf-8'), salt=bytes.fromhex('859c5d345ee58dfca293950c540016af3a889d0dacb00b8eff2ac2b150f0b07e'), n=262144, r=8, p=1, maxmem=2000000000, dklen=32)
Notice that we have taken the user-input password "a", together with the parameters "salt", "n", "r", "p", "dklen", whose values are from the keystore file. The output should be
>>> print(dec_key)
b'\xaeC\xdd\x02\xf98$h\x0b\x00\xfb\x83\x0c\xb9?\x04\xdd5\x91p\xfaM\xd4\xb7Ks\x9f0\xd3\xb1\xec\xd4'
The keystore file's "mac" field can be used for validating the last step's result, which should be a 32-byte array. According to documentation, the first 16 bytes are for the next step (decrypting the raw key), the second 16 bytes, concatenated with the ciphertext, after going through Keccak hashing, the result should match "mac".
>>> validate = dec_key[16:] + bytes.fromhex('f97975cb858242372a7c910de23976be4f545ad6b4d6ddb86e54b7d9b3b1c6a1')
>>> from Crypto.Hash import keccak
>>> keccak_hash=keccak.new(digest_bits=256)
>>> keccak_hash.update(validate)
>>> print(keccak_hash.hexdigest())
31ccb67e48aba5d64bf727a5c6589fd5857021540d25d12df31323f10ae2bf97
The output matches the "mac", thus proving the user-input password is correct.
This step is straightforward AES decryption. Many tools can be used, e.g. openssl. Here, for simplicity, we continue with Python3.
>>> from Crypto.Cipher import AES
>>> from Crypto.Util import Counter
Now feed in the "initial vector" value from the keystore file:
>>> iv_int=int('7fa01f1d0d6a7117382632028cb0c323', 16)
>>> ctr = Counter.new(AES.block_size * 8, initial_value=iv_int)
>>> dec_suite = AES.new(key, AES.MODE_CTR, counter=ctr)
Finally feed in the ciphertext and the first 16 bytes of the derivation key:
>>> plain_key = dec_suite.decrypt(bytes.fromhex('f97975cb858242372a7c910de23976be4f545ad6b4d6ddb86e54b7d9b3b1c6a1'))
>>> print(plain_key)
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
This matches the known "secret" value of 1.
dec_suite = AES.new(dec_key,...
. Also I had to use plain_key.hex()
Sep 12, 2020 at 12:01
dec_suite
doesn't produce the right output for me. The mac
variable does match, so it's correct up to that point.
Nov 20, 2020 at 11:11
You can use the web3 CLI tool to do this easily:
web3 account extract --keyfile ~/Downloads/keystore-file --password password
I'm assuming your mist client runs a geth node in background.
Export of unencrypted key is not supported on purpose after deliberating the risk to end users. #1054
Unfortunately it seems not to be possible to extract the unencrypted private key.
If you got the key file under keystore then that is your private key encrypted with a password (plus other metadata) . There is really no need to export your actual ec private key (unless you well wanna do math with it or I don't know). You need to know your password though. You can copy the key to another client or machine. If you unlock the account you can use this address to sign transactions, ... r/cvckff5
If you want to dig deeper you could try:
ethereum/go-ethereum's ethkey
tool can do this:
> ethkey inspect --private --passwordfile kottipass.txt UTC--2019-01-30T14-49-18.711193885Z--e5dfD67E3d46De4e2C918d894FdC591793492E53
Address: 0xe5dfD67E3d46De4e2C918d894FdC591793492E53
Public key: 046ab6d31f00e43df04226fbf8b16c62eed80eec200ac5d7f247fc3d15f3d1a27f7e9f74a214e7ddcef8a3618853622fd37354080959b17fe36d82a46a8c0aa41e
Private key: 0e459e429c4e36769e0ba7fad5acd3ac8627b9404a1f96f0a003fb22206c2d1d
You could also use the wallet functionality on EthTools.com.
This tool loads details about your address from your keyfile and displays them in an easily consumable manner.
Select (or input) your keyfile
Click advanced to view your private key
Using this tool is also explained here in video format.
From this post: Export Parity private key this go program on github https://github.com/afterether/eacct was very helpful in obtaining a private key for my Kovan account. Most other references mentioned no longer support obtaining private keys but give me keystores only.
You can also get the list of accounts with their private keys using the below script:
Install keythereum: npm install keythereum
Create a file getPrivateKey.js and add below lines to it.
const keythereum = require('keythereum');
const async = require('async');
const datadir = 'path/to/datadir/where/keystore/is/located';
const accounts = [ ]; // add the account addresses whose private key has to be extracted
let keyObject, privateKey, count = 0;
let result = [];
async.forEach(accounts, (element, cb) => {
keyObject = keythereum.importFromFile(element, datadir);
privateKey = keythereum.recover('accountPassword', keyObject);
result.push({
address: element,
privateKey: privateKey.toString('hex')
});
console.log('result: \n', result[count]);
count++;
cb();
},() => {
console.log('inside final callback of async.forEach: ');
console.log('result array: ', result);
});
The script makes use of the keythereum, please go through it for more details.
Execute the script using: node getPrivateKey.js