I have a openssl generated private key in the following form:

$ cat priv.pem

How can i convert this (preferably using bash/Perl/python) into a WIF that can be imported into (preferably) Electrum? Also Electrum confuses me a bit, it says

WIF keys are typed in Electrum, based on script type.

A few examples:

What does this mean? Wallet import format does not say anything about typing

3 Answers 3


How can i convert this (preferably using bash/Perl/python) into a WIF that can be imported into (preferably) Electrum?

OpenSSL .pem files contain base-64 encoding of the values encoded using DER. In case of private keys they use PKCS#8 explained in RFC5208. To extract the key itself, you first have to decode the base-64 string and get the key out by reading the DER encoding (the posted example is missing 1 byte since the sequence length is 0x74 but the remaining bytes that come after it is 0x73 bytes). If you want to use OpenSSL itself, try using this command:

openssl pkey -in priv.pem -out priv.key

This should give you the key bytes. Now you have to convert them to WIF (base-58 with checksum). Use your favorite bitcoin library (I don't have any python suggestion but there are many you could find on GitHub) that has byte-to-Wif functions.

What does this mean? Wallet import format does not say anything about typing

Your one private key gives you one public key that could be used in both compressed and uncompressed form in many different output scripts which then you will see as a different type of address (P2PKH script -> address starting with 1; P2WPKH script -> address starting with bc1; ...). So when the private key is imported in a wallet, the wallet either has to look for all the output script types (like what Bitcoin-Core does) or ask the user to explicitly include the script type (which is what Electrum does).
In other words when you import a private key in Electrum with p2pkh:<key> the wallet only checks the address starting with 1 (legacy or base58) and when import it with p2wpkh:<key> it only checks the address starting with bc1 (native SegWit or bech32) and so on.

As a side note, there is BIP-0178 that proposed extending WIFs to address this and also Electrum briefly used a different way similar to this BIP but stopped because of incompatibility with other clients.

  • 1
    DER encoding contains more than just the key itself, it includes things like the curve parameters. WIF just encodes the private key itself. So after decoding the base64 string, you still have to extract the actual private key. That's just a matter of looking up how DER encoding works and then finding the private key.
    – Ava Chow
    Commented Aug 25, 2019 at 6:10
  • OpenSSL supports 8 privatekey PEM formats, only two of them PKCS8, and the example in the Q is not PKCS8 format, it is SEC1. (And as you note, corrupted.) To convert to DER, you need pkey ... -outform der or ec ... -outform der. But you don't really need to; any language that can compute base58check or similar can decode base64 and select bytes. Commented Aug 25, 2019 at 16:04

Yes, you can import the private key generated by OpenSSL to Electrum, Bitcoin Core, Mycelium and some other Bitcoin wallets after converstion to the Wallet Import Format.

There is the bash script for the converstion: https://gist.github.com/GregTonoski/438992249df6e4bd613f9758421ff38a

Usage example:

$ openssl ec -in private_key.openssl.pem -text | grep -A 3 'priv:' | tail -n 3 | tr -d -c [:xdigit:] | xargs bash private_key_into_bitcoin_wif.sh > private_key_bitcoin.wif

The resulting text in the private_key_bitcoin.wif is accepted by Bitcoin wallets.

Side note: in case of Bitcoin Core the import works only for the non-descriptor type of wallet which is created like that: $ bitcoin-cli -named createwallet wallet_name="your_wallet_name" descriptors=false (the default setting is: descriptors=true).


Easiest way, use python

from bit import Key, PrivateKey, PrivateKeyTestnet

# Import PEM file
key = Key.from_pem('path/to/pem_file/here')

# Export to wif

WifFormat = Key.to_wif()


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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