Sunday, March 10, 2013

Ultimate Bitcoin Security

We'll discuss how to safely create and
spend from offline Bitcoin accounts.
In current events, the dreaded sequester (a round of across-the-board cuts in U.S. Federal discretionary spending) has kicked in, but US stocks have nevertheless attained new highs - despite troubling signs about global warming and the fragility of the boom in nontraditional crude oil extraction.  One wonders if stock market investors are again indulging in "irrational exuberance."

There's another class of investment that is also at an all-time high, and that has been performing even better than stocks:  Namely, the electronic currency Bitcoin.  There are good reasons for this:
  1. Bitcoin is gaining in mainstream acceptance, as the largest exchange (Mt. Gox) moves its trading operations to the U.S., in affiliation with an actual bank (Silicon Valley Bank), in preparation to meet demand from Wall Street investors for better-regulated access to the Bitcoin economy. Also, a licensed Bitcoin hedge fund is opening up in Malta.
  2. The underlying fundamentals of Bitcoin remain strong, with an underlying cryptographic protocol that still has never been hacked, and that will likely remain unhackable for the foreseeable future; Bitcoin remains the most secure and lowest-cost medium for the digital storage and transmission of wealth.
In previous posts, I have described how individuals can realize Bitcoin's secure-storage capabilities for themselves through the use of brain wallets and offline paper wallets.  However, one limitation of the techniques I described previously was that, in order to send Bitcoins stored in this way to another account, you had to enter your private key information into an online client program; this could expose you to a risk of having your coins stolen if the online computer had been hacked at some point.

The most secure Bitcoin accounts
or "wallets" are ones that are never
exposed to the Internet at all.
It turns out there is a safer way.  It is possible to generate a bitcoin transaction order (basically, an electronic cheque) entirely offline, which means that, during this process, you can make it virtually impossible for any of your private key information stored in the offline computer to escape to the outside world, even if that computer has been hacked previously and is running some malware.  Then, the generated transaction only -- which does not itself contain any private information -- can be moved to an online computer (via removable media such as an SD card or USB drive, say), and from there transmitted to the Bitcoin network.  (To be extra careful, you should verify the contents of the removable media on another, independent offline computer before you expose it to a network-connected computer.)

This then provides a means for a relatively technically unsophisticated user to remain 100% confident that his stash of Bitcoins remains safe from theft, while still retaining the ability to spend or transfer portions of that store of liquid wealth on demand, as needed.

In this post, I will describe this process.

Part I.  Creating an Unhackable Offline Wallet

One of the major premises of the method I'll describe here is "trust nobody."  If you plan to store large amounts of wealth in Bitcoin, and you expect the value of those Bitcoins to grow significantly in the future, and you are paranoid about somebody, someday, stealing that wealth, then you want to make extra-sure that it is totally unhackable.

The first step in this process is creating an offline Bitcoin account, that is, one where the critical private information required to access that account never touches any computer that is connected to the Internet.  This precludes your private data (and thus, your Bitcoins in that account) from being stolen by any electronic means - including compromised software.

Even so, you will need to use some software to run the algorithms required to compute your public Bitcoin address from a (typically randomly-generated) private key.  If the software you use for this purpose is not trustworthy, then it could do things like instead generate fake "predefined" accounts built into the software, where the authors of the software already have the keys to that account.  Given this risk, how can you make sure that your new Bitcoin account is generated as securely as possible?

The most essential requirement is that the random data that goes into selecting a key is truly randomly generated, and cannot be corrupted or influenced by an attacker so as to make it come out one way rather than another.  Once you have the initial random data, with confidence that it is secure, you can verify that it is being transformed to a Bitcoin account correctly by redundantly performing this standard transformation with several different pieces of software (on an offline computer), making sure that they all return the same result.  If they do then it becomes very unlikely that all those pieces of software were corrupted in the same way to give you a fake address.

This is a totally secure and unhackable
random-number generator.
Now, good random number generators are complex pieces of software, which would generally be difficult for the lay user to verify (to make sure they are generating high-quality, not-predictable random numbers).  Therefore, what I recommend is: don't generate your random numbers using a computer at all.  Instead, use a simple physical method, such as flipping coins or rolling dice.  In this post, I will assume that you have access to at least one ordinary, 6-sided die.  A pack of these can be purchased at many convenience stores.

Armed with a die, you are now ready to generate the truly random, private data needed to securely create a new Bitcoin account.  This can be done by hand, using a procedure which I will describe; however, to simplify and partially automate the steps of the process, I have written a little program to help you.  This program is simple enough that, if you know anything about computer programming at all, a quick look through it can convince you that it is not doing anything insecure.

First, I will describe how to download and run the program; then, I will take you through what the program is doing, so you can verify the code for yourself or (if you're not confident in your ability to do that), go through the steps by hand.

I(A).  Downloading and Running the Dice-Wallet Program

GitHub is a popular site
for hosting open-source
programming projects.
I have stored this program on the online source code repository GitHub, at the web address  GitHib is a popular site for sharing code and allowing users to propose improvements.  (However, I, as the original author of the dicewallet program, have the final say over whether any proposed change is integrated into the online copy.)

To download the program, you can either click the ZIP button (if you know how to unzip a file), or (perhaps easier), download the files individually, by, one file at a time, clicking on the file name and then clicking the "Raw" button, then selecting "Save as..." in your browser.  Save them all to the same folder.  

Python is a popular and easy-to-use
programming language.
Now, the program is written in the Python programming language; if you do not have Python yet, you can download the latest copy from  It's free.  Make sure you get version 3.x.x (a version number starting with 3), not version 2.x.x - the script will not work with Python 2.  

Note that using the Python language technically means you have to trust it.  But, if you don't even trust Python, which is one of the most popular and beloved of all computer languages, then may God have mercy on your soul.  (Anyway, you can always verify the program's output by hand if you're suspicious.)

How to run the program may vary with your operating system.  In Windows, double-clicking the dicewallet icon should be enough to start it, if Python has been installed successfully.  It should bring up a window that looks something like this (you may have to expand it and scroll to see the full contents):

Initial window contents when you run the program.
At this point you have a menu with three options, to select what size you want your randomly-generated data to be, measured in bits or binary digits.  The choices are:
  1. 64 bits' worth of random data.  This is relatively quick to generate, since it requires only 25 rolls of a 6-sided die.  The random information is translated for you by the program into a 5-word passphrase.  This is relatively easy to memorize, but it also might be cracked more quickly by a determined hacker.
  2. 128 bits' worth of random data.  This takes twice as long to generate (50 rolls), and (at 10 words long) is at least twice as difficult to memorize accurately.  However, it is much more difficult to hack
  3. 256 bits' worth of random data.  This takes twice as long again to generate (100 rolls) as the 128-bit option, at at 20 words is a challenge to memorize.  But it is virtually impossible to hack, and is at the very highest level of security that the Bitcoin system currently supports.
You might want to create dice wallets of several sizes (measured in terms of the amount of random data used to generate them), with short, easily-memorized ones for everyday use, and a very large (256 bit) one to store your life savings.  However, personally, even if you are good at memorizing, I don't recommend you rely on your memory alone; instead, you'll want to also print out copies of your random data, and store them in several secure locations (in a fireproof safe, or in a safety deposit box at a bank, etc.).  More on this later.

Let's now illustrate what happens when you enter option 3:

Dicewallet console after selecting option 3 (max amount of random data).
Note the program displays some information about your selected choice, and then loads the diceware dictionary.  This is a plain-text file which you should examine; it provides an English word or symbol corresponding to each of the 7,776 possible sequences of 5 die rolls.  The top portion of it looks like this:


11111 a
11112 a&p
11113 a's
11114 aa
11115 aaa
11116 aaaa
11121 aaron
11122 ab
11123 aba
11124 ababa
And so on.  At the very bottom of the file is a PGP signature which you can use, if you're really paranoid, to verify that the word list has not been modified; here's some information about where to get PGP by its original author.  GPG is a good substitute for most purposes.  Here's the signature in my copy:
Version: PGP for Personal Privacy 5.0
Charset: noconv

I downloaded the word list file originally from this link and some additional information about Diceware can be found on this page.  I'll sum it up below.

IMPORTANT:  For security, you need to go OFFLINE before doing this next step.  Unplug your computer from the Internet, turn off your router, disable its network interface - whatever you have to do.  The very safest thing would be to run the program on a computer that was set up from the original factory settings and was NEVER connected to the Internet.  However, even if it has never been connected to the Internet before, as long as it never WILL BE connected to the Internet in the future, you know your private data can't be hacked.  So, really paranoid users may want to reserve a dedicated computer for this sort of thing.

I(B).  Rolling the Dice

So next, you just need to start rolling your die, and entering the numbers, five at a time, into the program.  To save time, you could roll 5 dice at once, but if you do this, you should make sure they are different colors, or otherwise distinguishable, so that you can input them in a definite sequence.  If you didn't do this, and you subconsciously entered the results in some order that was correlated with the die values (say smallest to largest), you could bias the results, and reduce the randomness of your data.  Short of coloring the die, one simple way is to read off the dice in some definite order (left-to-right, say) across your field of view.

Let's show the screen after the first 25 rolls:

Diceware interface after entering 1st chunk of dice-roll data for a 4-chunk passphrase.

Note that the data entry is broken into "chunks" of 5 dicewords each (corresponding to 25 die rolls); each of these providing about 64 bits' worth of random data.  This is just done for organizational purposes.

Note the program is doing two things here:  Converting the die rolls to a number in base 6 (from 00000 to 55555), which will be used in a later step; and looking up the Diceware word corresponding to each group of 5 die rolls.  You can see that, for this first chunk, the 5 word sequence selected was "11 other porto wow nice."  If this was a 64-bit run, we would be finished with data entry at this point, and would have an easy-to-remember passphrase.

However, this is a 256-bit run, so we have 3 other chunks worth of die rolls (75 more rolls) to enter.  I'll skip the gory details of that process, and just show you the final result.  At the conclusion of the process, the final output is as follows (and this would look better on a wider terminal):

Final output of Dicewallet for a 256-bit random key.

Here is what the output would look like, with the same data, if the application is run within the IDLE editor that comes with Python:  You may find that a little easier to read since the long data strings aren't wrapping around.  (To get this in Windows, right-click the dicewallet icon, select "Edit with IDLE", then in that window, hit function key F5 or select Run --> Run Module from the menu.)

Dicewallet output in the IDLE environment.

So, a couple of things to note about the output here:

  1. The entered chunk of random data is displayed in several forms.  You may use any of these to generate a Bitcoin account.  The passphrase (sequence of words/symbols) might be the easiest to remember and to communicate to others.  But the decimal and hexadecimal passcodes (which are mathematically equal to the base-6 number derived from the die rolls) may be faster to type.  You might want to omit the commas when typing the decimal code.
  2. Since the entered data was actually a little more than 256 bits' worth, we can also generate a 256-bit hexadecimal Bitcoin private key directly by just taking the last 256 bits (64 hex characters, 32 bytes) of the hexadecimal passcode, and use that directly.  That is, this would not need to be put through a brainwallet key-generation algorithm to turn it into a private key - it is already a private key. 

I(C).  Making Your Public Address

Now that you have a randomly-generated passphrase or private key, how do you convert it to a public Bitcoin address that people can send money to?

As I've discussed in previous posts, perhaps the easiest way to do this currently is to download the HTML source code to the website, store it on your offline computer, and run it (without being connected to the network).  It is self-contained JavaScript in a single HTML file, and will run without needing to connect to any servers.  To verify that it is working correctly, you may want to compare the output with that produced by some other offline tool, such as an offline copy of, or the Casascius Bitcoin Address Utility.  (Or, compare output with an online tool such as, but with a "test" key that you are not planning to actually use.)

As an example, here's what shows for the above passphrase (here I'm using it online, just for demonstration purposes, but it works the same offline): after entering our 20-word random Diceware passphrase.

And, for comparison, here is with the same input: after entering the same 20-word random Diceware passphrase.

As you can see, both sites come up with the same account information, namely:
  • Public Bitcoin address:  1FuKeiWSyu6gAxFvWXs1hPzJRpUm5vBLQC
  • Private key (WIF format): 5J3rXKZWszMKgwdMUHbjNLN2XA9cW8jzkQDQCmtGat49g1BnsPi
So, both tools are working OK, and if we're still not sure, we can compare with a third tool.  (All offline of course.)

At this point, it's essential that you make multiple backups (paper and/or offline electronic) of this derived account data, or at minimum the passphrase that was used to generate it, to make sure that you will be able to recover any Bitcoins put into this account.  Again, I recommend paper backups in multiple secure locations that you have physical control over.  If you encrypt your electronic backups, be careful - this raises a sort of chicken-and-egg problem, where now you have to worry about forgetting the encryption passphrase, if it's sufficiently strong, so now you have to make backups of it, and you haven't really solved the problem.

In the next section, we'll discuss:  Now that you have this nice safe offline Bitcoin account, how can you securely send money from it, without needing to risk exposure of your private key data?

Part II.  Spending from Offline Accounts

In this part, I'll discuss:  Now that you have this nice safe offline Bitcoin account, how can you securely send money from it, without needing to ever risk exposure of your private key data?

The StrongCoin service proves a simple tool which you can run offline to generate your transaction details.  You can download it here.  To use it, you have to look up the transaction history for the Bitcoin address you are trying to spend coins from.  This can be done from the "mytransactions" query service at, using a URL starting with "" followed by the address.  I'll illustrate this process, step-by-step, for an actual example below.  I actually was forced to go through this process today to retrieve some coins from a paper wallet, because other clients were not accepting its private key for some reason.

Step 1.  Create Offline Wallet

I previously used (offline) to generate a paper wallet with the following details (safe for me to give out, now that the coins are emptied from it):

  • Private key:  5KVkdnmRqbiRvuvzQdMpiUbCyGrxJUzUpU83HNcbMK3tRT1BPqN
  • Public address:  1CrkvauazZGd7cegyYkw2PK4M9MMNmVNek

Step 2.  Fund Wallet

At some point, I sent 10 BTC to this address from another account, and then used to send 2 BTC from it to Mt. Gox, with a 0.001 BTC transaction fee, and sent the 7.999 BTC change back to the same paper wallet.

However, a little later, I ran into problems, because a temporary glitch in's transaction database prevented me from spending any of the remaining balance.  Fortunately, I still had my paper wallet printout, so I tried importing the private key into Electrum, as well as the official "Satoshi" client, now called Bitcoin-Qt (v0.8).  Unfortunately, these did not work either!  (I still don't know why yet.)  So, I decided to try out this offline spending method instead.

Step 3.  Find Account's Transaction History.

The next step is to obtain the complete transaction history of your account, in a certain format.  This can be done by going to followed by your account address, in my case  The complete output from this was:

        "scriptSig":"3046022100fa94cb6ce0810ad37972df074aa9f4477fd246e84731d6325e14a232f1fbab69022100fc531111e2dd49c2d8550c61fe0d1aca4de1b3f7158d07c55ee79fb7bb6e56db01 049da190afa6511f738d695b5c5178e890ff04e4f85b1ad7b83fa97d538b232c1067c9679facb04fea4120e0bb878871e5aeca02f11ebd1222938b616f1c938d82",
        "scriptSig":"3046022100a3ec31eb91a945f0288c5b5a8d055665800a5d279bec2104d38fe9f5ecf013cb022100820a2d203bd6f44120cd8b2f24604d6f3685392871048ab84eab26fa3f5559be01 0466f9e3fea3b01035369c2615a2546a74e0ee660814f5d540975c840aafb970c03f01424fee9b05b3966c33296b5150cedca602fcd35814e846af0b9dbf7d8e30",
        "scriptPubKey":"OP_DUP OP_HASH160 b7bbc94f4810f4b2baf5458d46ffe680668f082a OP_EQUALVERIFY OP_CHECKSIG",
        "scriptPubKey":"OP_DUP OP_HASH160 82126e7a2729c87a7ddd75577c87cc170429857a OP_EQUALVERIFY OP_CHECKSIG",
    "time":"2013-03-01 01:26:21"
        "scriptSig":"304402206bd8e1bbde33ba97a702e93286c764db4d1cdec8448c96b6d419d4055ca1756902206a78a3bb81db0a7d7a16d8f388de5f5b33e93f0418d3968ee9bb3596f9a053f201 04ee17f6e9f51926d9d07d19cd1d1bb73c993fb190fedbc2c6f1b8fa05d04682b62043076036e642fc80b176e3645edad73d8ff5bb5f2e4f571f620b2fd0fc4e44",
        "scriptPubKey":"OP_DUP OP_HASH160 305d8de76154bc34281c0fd582e652eae6f73d6b OP_EQUALVERIFY OP_CHECKSIG",
        "scriptPubKey":"OP_DUP OP_HASH160 82126e7a2729c87a7ddd75577c87cc170429857a OP_EQUALVERIFY OP_CHECKSIG",
    "time":"2013-03-08 01:52:32"
You can see, near the end, where I previously sent out two coins and sent myself back the 7.999 BTC change.

Step 4.  Generate Offline Transaction

Then, on your offline machine, you run StrongCoin's offlineTransaction.html page, and fill in the various fields (hitting the Parse button after the top two to verify your balance), and then hit the Generate button.  Then the tool gives you, in the last field, a long hexadecimal string which is the digitally-signed transaction order.  In my case, the screen looked like this:

StrongCoin's offlineTransaction.html tool, with fields filled in.

Step 5.  Move Signed Transaction Back to Online Computer

You can do this using an SD card, USB flash drive, or other removable media.  For safety, I recommend a bare card with no other data on it.  To be extra-safe, you should make sure that there really is no other data on the card by checking it on yet another offline computer that you trust has not been compromised.  If you are extremely paranoid, you can even avoid digital media, and just write down the transaction code on paper - that way, you know that no malware is stowing away your private key data in a hidden file somewhere on the media.

Step 6.  Insert Transaction Order into Bitcoin Network

This last step is very easy, but requires running a client that can handle raw transactions.  The default Bitcoin-Qt client does this, through its Debug console interface.  I used version 0.8.0 of the client.  Select menu Help --> Debug window, and click the "Console" tab.  The debug window then looks like this:

Bitcoin-Qt (0.8) Debug Console

At this point, all you have to do is type the necessary command name "sendrawtransaction" at the prompt, followed by a space, and paste your transaction data copied from the last field of the offlineTransaction tool, which in this case gives me:
sendrawtransaction 01000000015b2b675ab11740ffc54a19d17d81d147b56c7dfe91933850fa86e20cb3e5e687010000008a473044022028d0ecf4101826b3c9890480ff9e291fe22aa8b00d877d139b420027f4ab82800220d0197fc20a0bf96c3b660a01bd5ae06eb366e873d36d5736c146fa53dd5d85e8014104ee17f6e9f51926d9d07d19cd1d1bb73c993fb190fedbc2c6f1b8fa05d04682b62043076036e642fc80b176e3645edad73d8ff5bb5f2e4f571f620b2fd0fc4e44ffffffff01c0faab2f000000001976a9147781393fa77a8e3abc472bd430ca3f9424ba933688ac00000000
And hit enter.  The transaction (if properly formatted and verified) will then be immediately injected into the Bitcoin network.  You have to wait several minutes for block confirmation(s), as usual.  (Note that you cannot re-enter this same transaction, because those coins have already been spent; if you want to practice, you'll have to make your own!)

Or, even easier (and, this way, you don't have to wait for your full node to catch up to the block chain) - just visit and paste your transaction data there.  (Thanks to Eric Heaney for the tip!)

That's it for now!  Have fun playing with your offline wallets and offline transactions!


  1. Sorry to disappoint you, but this is wrong:

    "it is impossible for any of your private key information stored in the offline computer to escape to the outside world, even if that computer has been hacked previously and is running some malware. Then, the generated transaction only -- which does not itself contain any private information -- can be moved to an online computer (via removable media such as an SD card or USB drive, say)"

    Security doesn't work that way.

    Once a computer is compromised, you have to assume the worse: i.e. that the hacker foreshadowed correctly what you were going to do.
    Hence, when you move out your data, it could bypass you and write to the SD any data it chose to.

    Compromised computers are simply no longer trustable to do anything, under any condition, not even offline.

    1. OK sure, but you could inspect what is on the SD card from another offline computer... And if you suspect that that computer may be compromised as well, you could check it on several different ones, to be sure. The fact that some computers are offline gives you much more control over what data gets released to the outside world than if they are not. If I have several old laptops lying around, it is unreasonable to suppose they are all conspiring to hide the true contents of that SD card from me.

    2. Also: The truly paranoid could write down the transaction bytes and manually enter them for sending from a network-connected computer. However, to be REALLY sure this is safe you would need to parse the transaction details to be certain that the private key is not included.

    3. Here's a handy tool from that will decode your transactions for you... It's online but you can try it with a test account to make sure no private data is being snuck into your encrypted transactions.

  2. Congratulations to whoever claimed the 0.11 BTC that I put back into my paper wallet 1CrkvauazZGd7cegyYkw2PK4M9MMNmVNek after I had emptied it - I forgot that I had already published its private key as an example above, and I was still carrying a printout of its QR code in my wallet, and I used it to receive a small payment from a friend. Whoever you are, you got my lunch money! I'll be careful not to make that same mistake again. :)

    1. 0,11 BTC is a fairly cheap lesson ;)

  3. this waas a very good article for bitcoin geeks
    i like the way you explained everything ...
    i got this one more interesting article related to the same topic seems you should have a look over this ...

    the security of the whole thing is on sake due to gov interference

  4. When I press 3 and hit enter I see very quickly lines on the terminal and then the program closes. This happens on windows 7 and windows xp. What am I doing wrong.


  5. Thank you very much for this, very helpful.

  6. eToro is the best forex broker for beginner and full-time traders.

  7. If you're looking to buy bitcoins online, Paxful is the #1 source for bitcoins as it allows buying bitcoins by 100's of different payment methods, such as MoneyGram, Western Union, PayPal, Visa, MasterCard, American Express and even converting your gift cards for bitcoins.

  8. Ever tried automating your free satoshi collections by using a BTC FAUCET ROTATOR?

  9. Find out how THOUSAND of individuals like YOU are making a LIVING by staying home and are fulfilling their dreams right NOW.

  10. BlueHost is ultimately the best hosting provider with plans for all of your hosting requirements.

  11. Get free satoshis over at Moon Bitcoin. 163 satoshis every 1 hour.

  12. BitKONG: Fun and Addictive, provably fair bitcoin game.

    And most importantly, Claim bitcoins every 10 mins from the free faucet.

  13. Easy crypto multicurrency mining application & 1-click graphic miner.

    Mine effectively with your computer or smartphone. Download MINERGATE.

  14. Quantum Binary Signals

    Get professional trading signals sent to your cell phone every day.

    Follow our signals NOW & gain up to 270% daily.

  15. Join the 125,000+ traders who’ve already taken advantage of our user-friendly trading platform. They use FXB Trading because we are an FSA regulated broker, we collaborate with all the major crypto exchanges and there are no fees or commissions to pay. We can also offer 1:10 leverage for trading cryptos – which is hard to beat.

  16. Whether it's a cryptocurrency or its core technology blockchain development, scalablockchain has answers -