How to create a secure Bitcoin cold wallet

tednobs
12 min readApr 15, 2018

This post is going to detail my preferred cold storage method for storing Bitcoins. Unlike paper wallets (which I will detail my way to generate in a separate post) this process will put a level of separation in the coin retrieval process. This helps me sleep at night knowing there are two pieces of the puzzle for a potential attacker to figure out, unlike with a paper wallet containing mnemonic seeds that grant full access to the coins.

What you will learn from this guide:

  • Set up a secure environment for generating cold wallets
  • Verify the Bitcoin Core wallet software
  • Create an encrypted wallet file
  • Export a list of Bitcoin address for your cold storage
  • Redeem coins from the cold wallet
  • Storage ideas for safe keeping of cold wallet and passphrase

Reader note: creating cold storage manually is not for everyone, there are many hardware wallets available with decent community approval in the market today. You have to decide for yourself which method is right for you and your situation. The method outlined below and hardware wallets are not guaranteed to be 100% secure as there will be some level of “trust” required. With this route you have to trust the Linux live DVD and the Bitcoin wallet software we’ll be using, where as with a hardware wallet you’re putting your trust in the manufacturer and their process of creating the devices.

This guide assumes you are running Linux, here’s what we need:

  • An old laptop you have collecting dust
  • A blank DVD
  • A USB flash drive
  • The latest Ubuntu live DVD ISO
  • The latest stable Bitcoin Core Wallet
  • Pen and paper

Prepare environment & laptop

You want to perform these steps in a private location and ensure nothing is recording you — such as webcams, security cams, baby monitors, phone cameras, etc.

Use an old laptop you have been waiting to recycle, and repurpose for this process and this process only — it should never be used for anything else.

Get out your mini screw driver and start deconstructing — we want to remove the following:

  • Storage drives (HDD, SSD)
  • WiFi radio
  • Bluetooth radio
  • Webcam & microphone unit

The notebook should have an optical drive which we will use for running a live DVD.

Downloading & verifying the software

Grab the latest version of Ubuntu and after you have the ISO you must be sure the verify image to ensure data integrity and authenticity of the download.

Download: https://www.ubuntu.com/download/desktop
Verify: https://tutorials.ubuntu.com/tutorial/tutorial-how-to-verify-ubuntu

The verification process is spelled out step by step in the Ubuntu tutorial so there’s no point repeating, I will however detail the verification process for the Bitcoin wallet. After you verify the file burn the image to a DVD — we will only be using the DVD for this process, be sure to label the disk accordingly.

Now it’s time to grab a Bitcoin wallet, we are going to use Bitcoin Core. I have come to “trust” (through years of verification, community interaction, and use of) the Bitcoin Core wallet as it’s the reference implementation and has an amazing development team, but please do your own research and come to your own conclusions on the validity of this software before putting your trust in it. You can read about it here: https://bitcoin.org/en/bitcoin-core/.

Download the latest Linux (.tgz) file: https://bitcoin.org/en/download — also be sure to download the release signatures (SHA256SUMS.asc) from the same page, and move both files into the same directory.

We are going to verify the file using two different methods, the first will get the sha256sum of the file and compare to the hash in the SHA256SUMS.asc file.

sha256sum bitcoin-0.16.0-x86_64-linux-gnu.tar.gz

After you compare the output to the values in the downloaded .asc file, it’s good to also verify on a secondary source online. I like to use a post by the infamous reddit administrator theymos on Reddit: https://www.reddit.com/r/Bitcoin/wiki/verifying_bitcoin_core — locate your file by searching the page and compare the hashes, this post is updated by BashCo for new versions so it’s typically up-to-date.

Now we have to take the verification process a step further to make sure the hashes are signed by trustworthy developers.

First we have to import keys, I put my trust in Wladimir J. van der Laan as he has proven himself to be an invaluable member of the Bitcoin the community.

Wladimir J. van der Laan
0x71a3b16735405025d447e8f274810b012346c9a6

gpg — keyserver pgp.mit.edu — recv-keys 2346C9A6

Now that we have Wladimir’s keys imported we need to grab his signatures for the wallet version we’re working with, for this guide the proper location is: https://github.com/bitcoin-core/gitian.sigs/tree/master/0.16.0-linux/laanwj — download both files (.assert & .assert.sig) and throw them in the same directory we’ve been working in.

Verify the signature:

gpg — verify bitcoin-linux-0.16-build.assert.sig

OK awesome, it’s a good signature from Wladimir! One last thing to check — open the .assert file in a text editor (bitcoin-linux-0.16-build.assert) and locate the hash for the wallet file we downloaded originally (bitcoin-0.16.0-x86_64-linux-gnu.tar.gz) and verify the hash is the same from our first verification step of the sha256sum output. If we have a match we’re good to continue.

Beware: the above steps of downloading the Linux live DVD and Bitcoin wallet are points of risk — you must be confident the ISO and Wallet files are authentic. You must verify, if you get bogus software you’re gonna have a bad time. Do not perform those steps on any workstations which may be compromised.

Cold wallet creation process

We now have our Linux live DVD and our Bitcoin Core software, next copy the Bitcoin Core file (bitcoin-0.16.0-x86_64-linux-gnu.tar.gz) to a clean USB flash drive.

Boot your newly repurposed laptop with the Ubuntu live DVD & be sure to select “try” opposed to the option to install the OS. Once the operating system is running insert the flash drive and uncompress the file to the ~/Documents directory then remove the flash drive, move into the following directory and run bitcoin-qt:

cd ~/Documents/bitcoin-0.16.0/bin/
./bitcoin-qt

Use the default data directory and the wallet will attempt to connect to peers which it obviously won’t be able to since we’re offline.

Wallet encryption passphrase

The next step will be encrypting the wallet — it is very important to use a good passphrase for this process, and even more essential that you remember it. We never want a digital copy of this passphrase to exist, so grab two pieces of paper and a pen. I generate a random string of around 40 characters long using various offline methods — this guide will use the following command as an example, however this should not be performed on the laptop we’re using in this guide as we don’t want any chance of this jumping over to our USB flash drive later on.

openssl rand -base64 32 | tr -d /=+

How ever you decide to generate your random passphrase is up to you. Offline storage of this phrase is the key, so grab your two sheets of paper and slowly write the code on each page.

This process of writing the passphrase on paper is a point of failure, in the case you incorrectly copied the code — so we are going to verify both sheets before moving on.

From the settings menu in the Bitcoin Core wallet choose “Encrypt Wallet”, enter your passphrase and hit OK, after this the software will close.

The wallet file is now encrypted using our passphrase so lets open the software again and verify our paper copies are correct — use the ./bitcoin-qt command to open the wallet back up.

From the help menu choose “Debug window” — and using copy number one of your passphrase paper enter the following command to verify it is correct.

walletpassphrase your-passphrase-here 10

If the wallet was successfully decrypted you get a simple one line output of “null” — if the passphrase is incorrect it will display an error. The following screenshot shows three commands in succession:

  1. walletpassphrase with-an-incorrect-password 10
  2. walletpassphrase with-the-correct-password 10
  3. walletlock

As you see the first command produced the error output, then the second two commands completed successfully with the output “null”. Make sure you run the walletlock command, and verify the second paper copy of the passphrase.

Now that we have verified both passphrases are correct, seal them up in separate envelopes, properly mark so you remember what they are, and put aside for safe keeping at this point.

Cold storage addresses and wallet file

From the Bitcoin Core file menu select “Receiving addresses…” which brings up a dialog and from here hit the “New” button then OK. Depending on your situation, you may want more than one address, I typically create five. After you generate the amount of address you want, use the “Export” button and save the .csv file to ~/Documents.

Now we will create a back up of the wallet.dat file into the ~/Documents directory. From the file menu in Bitcoin Core choose “Backup Wallet…”, enter a name and save.

At this point we have everything we need:

  • paper copies of our passphrase which have never seen digital form
  • a list of our cold storage addresses
  • our encrypted wallet file

Close the Bitcoin Core wallet software, insert a clean USB flash drive, and copy the .csv and .dat files over.

Safely eject the flash drive — be sure to leave the laptop on for a minute while we plug the drive into our main workstation to verify both files successfully copied. Make a copy of the files on your computer, and keep the files on the USB flash drive — after you’ve confirmed the files are safely on your workstation and on the flash drive you can turn off the laptop.

Congratulations, you now have a secure cold wallet!

Funding & redeeming

The exported .csv file contains five Bitcoin addresses which you can now use for funding the cold wallet. There is nothing special about them so you can send coins to them as you would any other address, but obviously you should reserve these address longer term secure hodling. Feel free to check the balances of these addresses with online blockchain explorers (take into consideration these services most likely log your IP address & search queries).

Note on watch only addresses. Many people like to generate watch only addresses from their cold storage wallets — personally I’ve never had the need for them, but they can be extremely convenient for a lot of situations. With watch only addresses you can keep track of your cold storage addresses in an active (online) wallet with out the ability to spend the coins as the associated private keys are not present. You can read more about them here: https://bitcoin.org/en/glossary/watch-only-address.

When the time comes to access the funds there are several ways to get the job done. I prefer the safe and conventional approach which is to use Bitcoin Core again. Grab a fresh copy of the wallet software on an Internet connected workstation with enough storage space and sync the node, depending on your set up sync time will vary, but typically on the hardware I use at the time of this post it takes about 2 days. After you’re fully synced close Bitcoin Core and open the data directory which is located by default in ~/.bitcoin — in here you’ll see the wallet.dat file. If this is a fresh install with no Bitcoin sent to the wallet you can safely delete this file, or feel free to move it somewhere. Now we want to grab our cold storage wallet.dat file and move it into this directory, and start bitcoin-qt with the -rescan flag.

The rescan will force the wallet to look for transactions related to the addresses from the cold storage file. At this point you should see your balance and it should be spendable using the phasephrase we encrypted the wallet with earlier. Now that the cold wallet is on an Internet connected device and has been unencryted it’s important to note this is no longer a cold wallet — you will need to repeat the process and completely empty this wallet in the event you need cold storage again.

Note about redeeming. There are other ways to spend the funds from the cold storage wallet without the need to download the full blockchain as I recommend above. You can use Bitcoin Core offline and unsynced to create a raw transaction, sign the transaction, and then use an online machine to push this transaction onto the network using a service such as https://blockchain.info/pushtx. Another option would be to grab the private keys from the cold wallet and import them into a lightweight wallet client such as Electrum. Just be careful, as dealing directly with private keys and raw transactions can be difficult.

Storage considerations

The beauty of this method is that both pieces (passphrase & wallet.dat) are required to access the coins. This makes certain storage scenarios a bit more flexible — just be aware if the wallet.dat and passphrase are stored in the same location, you (or an attacker) has all they need to move the coins.

A possible storage configuration could be to give a trusted family member a copy of the passphrase to store in their secure location (home safe, safety deposit box), and the other copy of the passphrase in your safety deposit box along with recovery instructions for your loved ones. The wallet.dat file should not be stored in either of those locations, rather you can keep copies of that in separate locations as well — one on a flash drive at home, another flash drive at your office, and a third copy in one of your cloud drive accounts. In this configuration if any one of the locations are compromised you’ll have time to react and safely move the coins.

Note on cloud storage. You may think I’m crazy by storing the wallet.dat file online where corporate overlords or the overreaching deep state agencies could potentially grab a copy, but there are a few factors that make me OK with this. First, I know myself — and after a decent amount of time goes by there is definitely potential for me to lose the wallet files. But more importantly, it doesn’t matter if my cloud provider or the gubbermint copies my wallet.dat file — it’s encrypted. Assuming you used a decent passphrase with a high number of entropy bits (>120), it would take the worlds strongest supercomputers trillions of years to brute force, yes trillions of years. You could store the USB drive on a park bench and have no worries. Choose what is right for you.

Be sure not to have a single point of failure on that file. For instance if you only had two USB flash drives with the wallet located in your house — an extreme situation such as a fire could lose your coins forever.

And that’s it, hope you enjoyed it.

Sources:

https://www.ubuntu.com/download/desktop
https://tutorials.ubuntu.com/tutorial/tutorial-how-to-verify-ubuntu
https://bitcoin.org/en/bitcoin-core/
https://www.reddit.com/r/Bitcoin/wiki/verifying_bitcoin_core
https://pgp.mit.edu/pks/lookup?search=0x71a3b16735405025d447e8f274810b012346c9a6
https://keyserver.ubuntu.com/pks/lookup?op=vindex&search=0x71a3b16735405025d447e8f274810b012346c9a6
https://github.com/bitcoin-core/gitian.sigs/tree/master/0.16.0-linux/laanwj
https://bitcoin.org/en/glossary/watch-only-address
https://blockchain.info/pushtx

--

--