So I tested making a secure paper bitcoin key-pair today using some of this information as a starting point. A key-pair contains a public key and a private key which are mathematically linked. I wanted to do this because of a need for high security of the private half of the key pair. If you are really going to move significant value into bitcoin, security of the key-pair is important. Ironically, it seems like paper is one of the most secure ways to prevent the theft of the key. It is possible to physically secure a print out and it takes a lot more work to get to it than just breaking into a computer and stealing a file, which for a hacker seems easy.
A bitcoin key-pair is a way to create an “account” from and to which you can spend and receive bitcoins. The private key is required in order to spend money from the account. The public key is required in order to send money to the account. Generally one wants to keep the private key very secure so that other people can’t spend your bitcoins: like cash that you put in the mail, once you send bitcoin you can’t easily get it back.
A “wallet” contains zero or more key-pairs.
It is also important that you don’t lose your private key. That is considerably easier to manage as you can simply create several paper copies and distribute them in diverse secure locations.
To create a key-pair which is secure against theft and in particular spyware I did the following:
- I used VirtualBox for Mac and created a new virtual machine on my computer that was not connected to the Internet.
- I installed Ubuntu 11.10 on it from an .iso image.
- I downloaded a copy of bitaddress.org, a client-side bitcoin key-pair generator onto a thumb drive
- I mounted the thumb drive in the virtual machine
- I opened the offline copy of bitaddress in the virtual machine
- I generated a key-pair in a browser
- I printed it to a .pdf on the thumb drive
- I mounted the thumb drive on the host Mac and printed out the paper wallet.
- Then I used the “shred” utility to destroy the pdf file.
Some possible places where this could be insecure. My key would be compromised:
- … if my host computer had some kind of spyware on it that was doing a live screen capture and sending it somewhere. The screen capture would have the private key on it in the pixels that were shown from the virtual machine. If a bad guy got the screen capture she could spend my bitcoin.
- … if the code that I downloaded from bitaddress was compromised to give me a non-new or non-random key-pair. Then whomever wrote the code could just try the key-pair they knew I was going to generate to spend my bitcoin.
- … if I didn’t delete the pdf with the bitcoin address on it securely. Then the bad guy could recover the document from my Trash can or forensically from the hard drive.
- … if Time Machine captured the pdf and stored it for automatic backup. (I didn’t move it off the thumb drive to avoid this.) Then the bad guy could find the key in my backed up hard drive data.
- … if the print process were compromised (e.g., as described here). This is similar to the screen capture attack but with printers.
Finally to see that my system worked, I sent a small amount of bitcoin to the public key on my paper wallet.
- In the process of doing this I realized that the QR codes that I printed out on my paper wallet were too small to scan. This is actually really important because when you send coins, you don’t want to mistype the address you are sending them to. You can never get them back. So it’s better to automatically enter them.
- I found that so far, it only looks like Mt. Gox will let you enter a private key to retrieve funds. They treat it like you are redeeming a gift card which I think is clever. At first, it wasn’t clear that it worked though, so I started looking for another option and found pywallet. While I was messing with pywallet, Mt. Gox posted the balance from the private key and transferred the money from it to my Mt. Gox account. This is great as long you trust Mt.Gox because they can send the bitcoins anywhere they like.
- I also used the pywallet program. This python script lets you add a private key to your local bitcoin wallet. In the process I edited my wallet while my bitcoin client was running (despite the warnings) and corrupted my wallet. I lost an hour restoring my backed up wallet. (Thanks Time Machine!) In this process I learned that pywallet doesn’t yet work with encrypted wallets. So to recover funds from a private key, start a new unencrypted wallet, import your private key with pywallet, immediately transfer the bitcoins from the private key to a key in an encrypted wallet.
- I also ended up with a transaction in my bitcoin client that I didn’t understand. That made me nervous.
I wasn’t very happy with how smoothly the first paper wallet went, so I tried it again using the lessons learned and it went much better:
- I made a new paper key-pair in a virtual machine.
- I printed it out as a pdf on the thumb drive
- I moved the thumb drive to my Mac and verified that I could scan the codes when I printed it out at a higher scale.
- I sent some bitcoin to the public key of the paper key-pair.
- Once the transaction was confirmed I shut-down the bitcoin client, moved my normal encrypted wallet.dat file away
- I restarted the Bitcoin client which created a new unencrypted wallet.dat to manage the paper key-pair.
- I shut down the Bitcoin client
- I loaded the paper private-key into the unencrypted wallet.dat using pywallet.py
- I started the Bitcoin client with the unencrypted wallet.dat and sent the balance from the paper key-pair back to my normal wallet.
- I shutdown the Bitcoin client
- I replaced the original encrypted wallet.dat file and verified that bitcoin went back to my original wallet.
Mission Accomplished!






