How do I get the raw private key from my Mist keystore file?

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

    So there's no way to do this directly in geth?

    Also note that now disabled this option from it's online site too for security reasons. You can still do it with the downloadable offline version.

    I see. MEW seems to also have disabled this in the meantime.

  • 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


    for macOS use './Library/Ethereum' instead of './Appdata/roaming/ethereum' (Windows)

    I'm getting `aes-128-ctr is not available`:

  • 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


    • a keystone file
    • its password


    • 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*

    (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,

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

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

    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.update(validate)
    >>> print(keccak_hash.hexdigest())

    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 = * 8, initial_value=iv_int)
    >>> dec_suite =, 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)

    This matches the known "secret" value of 1.

    If we don't have any offline visual tools to do the recovery, I guess it means that Ethereum is dead and there's no use to recover. But it's still great to have a bare-bone answer to this issue and maybe will help people to understand how accounts are working. Thanks.

    It should be `dec_suite =,...`. Also I had to use `plain_key.hex()`

    Using the `dec_suite` doesn't produce the right output for me. The `mac` variable does match, so it's correct up to that point.

    It actually should be dec_key[0:16], not dec_key or key.

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

    Can't extract private key from wallet json file?

    Yes via the "View Wallet Details" tab. Feel free to run offline / locally too.

    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.

    @5chdn I made my comment an answer.

  • You can use the web3 CLI tool to do this easily:

    web3 account extract --keyfile ~/Downloads/keystore-file --password password

    short and sweet!

  • You could also use the wallet functionality on

    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.

    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?

    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.

  • 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
  • From this post: Export Parity private key this go program on github 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);
            address: element,
            privateKey: privateKey.toString('hex')
        console.log('result: \n', result[count]);
      },() => {
        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

License under CC-BY-SA with attribution

Content dated before 7/24/2021 11:53 AM