Dev Notes

Software Development Resources by David Egan.

Import Private Key from Bitcoin Paper Wallet to Bitcoin Core


Bitcoin, Cryptocurrency
David Egan

Import a private key from a BIP38 encrypted Bitcoin paper wallet to a Bitcoin Core (Bitcoin-QT) client wallet.

This article outlines how to import a BIP38 encrypted private key (for example, a Bitcoin paper wallet) to a Bitcoin Core wallet. This process allows the Bitcoin Core client to access and control the funds associated with the paper wallet Bitcoin address.

The process is quite involved - and much of the online documentation is either incomplete or outdated.

Note: this article describes importing rather than sweeping the paper wallet.

Importing vs Sweeping

Importing a private key hands control of the Bitcoins linked to the paper wallet to the Bitcoin Core client - the funds remain attached to the original Bitcoin address, as the private key is only imported. As such, if others have access to the paper wallet private key, they would also be able to gain access to the funds.

In contrast sweeping the private key involves making a transaction whereby all Bitcoins held on the wallet are sent to a new address managed by the receiving client - leaving the original (paper) wallet empty, and the funds in the full and exclusive control of the Bitcoin client.

The Bitcoin Core client does not have a built in function for ‘sweeping’ funds. Other wallets, such as the Electrum desktop client, Mycelium mobile wallet do have this function. I haven’t checked these.

Decrypting the Private Key

Access to the private key equates to full control of the funds attached to the Bitcoin address. Be careful not to expose the private key during the decryption & import process.

Decryption can be done using bitaddress.org. Download bitaddress.org and run locally after verifying the downloaded copy. For extra security (or added paranoia, depending on your viewpoint), run a verified copy of bitaddress.org in an offline Tails session. You could use Tails along with a persistent encrypted data partition on a USB drive with any offline computer to generate/decrypt Bitcoin private keys.

To decrypt the private key:

  • Download and verify a copy of bitaddress.org - e.g. bitaddress.org-vX.X.X-SHA256-XXX.html

Optional - for Extra Security

  • Copy bitaddress.org-vX.X.X-SHA256-XXX.html to a newly-formatted USB key
  • Disconnect computer from the internet
  • Boot into a Tails session
  • Add encrypted persistent storage the the Tails USB drive
  • Store the bitaddress.org-vX.X.X-SHA256-XXX.html file in ~/Persistent/Tor Browser/ (Note that Tor restricts local file directories - location matters)

If you’re certain that your system is secure (without malware or keyloggers etc), you could skip the previous steps and just disconnect from the internet. Personally, I take the time to run a verified bitaddress.org copy in an offline Tails session.

Common Actions

  • Navigate to a local copy of bitaddress.org-vX.X.X-SHA256-XXX.html in a browser
  • Click “Wallet Details”
  • Enter the encrypted private key
  • Select “BIP38 Encrypt?”
  • Enter the encryption passphrase that was used to generate the encrypted key
  • Click “Decrypt BIP38”

The decryption output includes the Bitcoin address, as well as public and private keys in a wide range of formats, including:

  • Uncompressed Bitcoin Address
  • Compressed Bitcoin Address
  • Public Key Uncompressed (130 characters [0-9A-F])
  • Public Key Compressed (66 characters [0-9A-F])
  • Private Key Hexadecimal Format (64 characters [0-9A-F])
  • Private Key Base64 (44 characters)
  • Private Key BIP38 Format (58 characters base58, starts with ‘6P’) - the original encrypted key
  • Private Key, Wallet Import Format
  • Private Key, Wallet Import Format Compressed - this is probably what you need.

Compressed vs Uncompressed Address/Private Key

Both compressed and uncompressed Bitcoin addresses are generated from the public key. The compressed version of the public key is almost half the size, and generates a Bitcoin address that is distinct from the uncompressed public key.

Because compressing keys significantly reduces blockchain space without losing any data, compressed keys are the recommended default.

To access funds, the compression state of the keys must match. If you’ve sent funds to the Bitcoin Address generated from the compressed public key, you’ll need to import the compressed Private Key (i.e Wallet Import Format compressed).

If you generated your paper wallet using bitaddress.org, the Bitcoin addresses on the paper wallet are compressed.

This means that you need to import the Private Key WIF Compressed. This address has 52 base58 characters and starts with a ‘K’ or ‘L’.

If you accidentally import the uncompressed private key, you’ll probably see a balance of zero. This doesn’t mean you’ve lost funds - you would have sent funds to the compressed address, and you therefore need to import the compressed private key.

Importing The Private Key

This is accomplished with the importprivkey command in the Bitcoin Core CLI. This command adds a private key to your wallet - it would also serve to import a private key as created by the dumpprivkey command.

The importprivkey command has the format: importprivkey “Kthebitcoinprivkey” ( “label” ) ( rescan )

Arguments:

  1. “bitcoinprivkey” (string, required) The private key (see dumpprivkey)
  2. “label” (string, optional, default=””) An optional label
  3. rescan (boolean, optional, default=true) Rescan the wallet for transactions

Note: This call can take minutes to complete if rescan is true.

Examples:

# Dump a private key
bitcoin-cli dumpprivkey "myaddress"

# Import the private key with rescan
bitcoin-cli importprivkey "privatekey"

# Import using a label and without rescan
bitcoin-cli importprivkey "privatekey" "testing" false

# Import using default blank label and without rescan
bitcoin-cli importprivkey "privatekey" "" false

# As a JSON-RPC call
curl --user myusername --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "importprivkey", "params": ["mykey", "testing", false] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/

Resources


comments powered by Disqus