Creating a truly secure Brain Wallet for storing your bitcoins

For Bitcoin users, the quest for a secure, yet easy to use method for wallet creation has become one of the most significant issues that must be addressed. If your wallet is not secure, your coins may be stolen and much value will be lost.

Several approaches to wallet creation have been proposed - one of the simplest and most promising is the Brain Wallet. A brain wallet is created from a passphrase supplied by the user. The advantage of the brain wallet is that the wallet can be recreated on the fly using only the passphrase. Thus, in a sense, the bitcoins contained in the brain wallet are stored in the owner's mind.

Most brain wallet methods involve a fairly simple scheme for converting a passphrase into a bitcoin private key. The most common example is:

 sha256(passphrase)

where sha256() is a hashing algorithm that is well-known to bitcoiners everywhere. Creating a brain wallet using this simple approach gives you an address that looks random, but is really not. For example, if a bitcoin address is created using this method with the passphrase "Bob is a great guy" (without the quotes), you get the public address:

 16veZVgnfaGTrJrXhbbjqceQan55nvwMTh

and the private key:

 5KBVcBXjpfyeHAJWJVr3o2yxGU4qgGbkFw6XgNjMgc58y4UqQuo

These look good, but are they random enough so that the private key is not discoverable? Absolutely NOT! Another guy named Bob might also feel he is a great guy and so accidently stumble on the same key, or a nefarious attacker using his bitcoin mining apparatus to hash simple passphrases based on the dictionary would not take very long to crack this private key and steal all of the bitcoins within. Even more complex passphrases can be vulnerable to attack using these simple private-key generation schemes. And as brain wallets become more popular, >attacks along these lines are becoming more and more prevalent.

Secure Brain Wallet Key Generation

In this section, I will describe how to create a secure brain wallet using the standard cryptographic techniques of salting and key stretching, as well as provide a simple bash script to create such keys. The execution time of the script is negligible, and it should run on most unix systems.

You can grab the script here. The brainwallet.zip file should be extracted into the same directory where your salt.aes file (see below) is stored.

The technique of salting a passphrase involves adding a random string of suitable length (the salt) to the end of the passphrase before hashing the passphrase+salt combination to get a bitcoin address.
In principle, the salt should be a random string of suitable length to make attacks time-consuming and difficult. In practice, a string of "high entropy" and length of the order of 64 bytes works well. You can make up your own salt (just be sure its as close to random as possible) or obtain one from a web page that specializes in generating random password strings such as this one. Select the string of "63 random alpha-numeric characters" that the site gives you and save that in a file called salt. If you prefer more security, you can make the string in your salt file even longer, by concatenating multiple 63-character strings into a single string. The bash script will use whatever is in the first line of the salt file. Also, keep in mind that you only need to create the salt file once. Once you have your salt file, you will need to encrypt it using the encrypt.sh bash script included in the zip archive. To do this, type:

 ./encrypt.sh salt

and type a password twice. This password is not related to your bitcoin wallet, but only serves to encrypt your salt. Do not forget this password! You will need it every time you re-create your brainwallet from a passphrase. Also, do not lose your encrypted salt file (salt.aes). This file is necessary to recreate your brainwallet.

Once you have your salt - encrypted - in the file salt.aes, you are ready to create a brainwallet. The brainwallet.sh script works as follows:

  1. Read in salt and passphrase
  2. hashNew=sha256($passphrase_$salt)
  3. hashOld=$hashNew
  4. hashNew=sha256($hashOld_$salt)
  5. Repeat items 3 and 4 254 more times
  6. Output hashNew as your private key

By concatenating the salt with your original passphrase, and hashing that combination, the script is adding strength (entropy) to your passphrase. The strength comes from the randomness (entropy) of your salt so make it a good one. Then, the script stretches your private key by hashing the concatenation of the output hash with your salt a total of 255 more times. This makes any kind of attack based on guessing your passphrase much more difficult and time consuming (a good thing!). Further, since everyone will have a different salt, even if two people start with identical passphrases, they will generate different private keys.

All of the hashing and keystretching described above is performed by the script and you really don't need to understand it. Just run the script with your passphrase:

 ./brainwallet.sh passphrase

and you will get out the private key associated with your passphrase. Note that if your passphrase has spaces in it, you should surround it with double quotes, e.g.:

 ./brainwallet.sh "this is my long passphrase"

You can then import that private key into the wallet of your choice to generate the bitcoin address people should send your coins to. If you are using the original bitcoin client bitcoind, the following commands will work:

 ./bitcoind importprivkey <yourprivatekey> <accountname>
 ./bitcoind getaccountaddress <accountname>

where <accountname> is a name you want to give this account inside your wallet and <yourprivatekey> is the private key you generated with the brainwallet.sh script. The second command will spit out your bitcoin address. Then if you like, you can delete the wallet (test this first to make sure everything works as expected before you delete a private key with a large amount of coins in it), because you can easily re-generate the private key with the brainwallet.sh script. Also, make sure you do not delete a wallet with private keys in it that you can not recreate.

Donations

If you found this secure brain wallet tutorial helpful, a donation to my bitcoin address:

1H8eUP2SqBtY2MpgomXbmsb11VNoZSSxJ7

would be greatly appreciated! Note that this address was created using the brainwallet.sh script!

Challenge

The method of generating brain wallets I've described above is an excellent and secure way to make use of the brain wallet idea. In fact, I'm convinced that this wallet is so secure, I'd like to propose the following challenge.

As users find this brain wallet method useful, they will add tips/donations to my bitcoin brainwallet address listed above.
I've also seeded the wallet to start things out. My challenge is that if anyone can crack the private key for my tip/donation wallet, they can keep all of the bitcoins in the wallet. I will even give you the passphrase the wallet is based on. That passphrase is my name: Dave.

In return, if you try to crack the wallet private key and are unsuccessful, I would encourage you to add something to the wallet to increase the incentive for others in the future. I will run this challenge for one year from its announcement date: Sept. 18, 2012.

The bitcoin block explorer gives the current holdings associated with this address: 1H8eUP2SqBtY2MpgomXbmsb11VNoZSSxJ7

Dave

PS: One final note - although the ideas underlying this brain wallet script are sound, the information is provided without any warranty of any kind. Use at your own risk.

All code, text and images are Copyright © 2013-2017 by David R. Andersen. All rights reserved unless otherwise specified.
This site is produced using the Haggis static site generator.