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.

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')

  • for macOS use './Library/Ethereum' instead of './Appdata/roaming/ethereum' (Windows) – Jay P. Jul 20 at 19:46

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:

  1. importing your keys from geth into eth using the ethkey utility. And after that you should be able to
  2. make the plain unencrypted private key visible with listbare (not recommended), and finally
  3. sign a message with eth_sign rpc call.
  • 1
    Can't myetherwallet.com extract private key from wallet json file? – Nicolas Massart May 8 '16 at 12:20
  • 1
    Yes via the "View Wallet Details" tab. Feel free to run offline / locally too. – tayvano May 8 '16 at 15:40
  • 1
    Go ahead and post another answer. 3 answers per question is good, only 1 answer per question needs some work. On a healthy site, questions receive multiple answers and the best answer is voted to the top. – Afri May 9 '16 at 8:38
  • @5chdn I made my comment an answer. – Nicolas Massart May 9 '16 at 13:46

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.

The Goal

Given

  • a keystone file
  • its password

output:

  • The raw 256-bit integer secret, which is the private key.

with steps

  • as "bare metal" as possible

Test steup

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".

Decryption

As explained in answers to this question here,

  • the raw private key is encrypted in the keystore file's "ciphertext", with the given algorithm and parameters (e.g. in our example, it's aes-128-ctr and an initial vector).
  • The key to decrypt the above is not the user input password (i.e. "a" in our case), but is the result of feeding the user input password into the specified kdf (key derivation function) algorithm (in our case, it's scrypt).

Obtaining the derivation key

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'

Validating the derivation key

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.

Decrypting with the derived key

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.

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.

The load wallet screen The load wallet screen

Select (or input) your keyfile Load your keyfile

Click advanced to view your private key View your private key

Using this tool is also explained here in video format.

  • 1
    It doesn't seem like good advice to use an online tool to decrypt a private key... Forgive me if I'm missing something, but how can someone be sure the website is no storing every data one inputs? – Renan Oct 16 '17 at 11:54
  • 1
    You are not missing anything. You are absolutely correct. You should be very careful when trusting your private key to a web based service. There are ways to check that a website is not storing your data but it is quite complex for anyone without a tech background. In this case, as this is my companies product I can assure you that we do not store your private keys. I would personally always advise having a cold wallet and then having an active wallet (that never holds significant amounts of Ether) that you use to interface with unknown services. – Thomas Clowes Oct 16 '17 at 12:23

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.