Use Secure Passwords for your Self-Generated Private Keys

One of the lesser known features of Bitcoin is that the private keys, which form the basis for a Bitcoin address, do not need to be generated randomly;
One of the lesser known features of Bitcoin is that the private keys, which form the basis for a Bitcoin address, do not need to be generated randomly;
Privacy & security - Use Secure Passwords for your Self-Generated Private Keys

One of the lesser known features of Bitcoin is that the private keys, which form the basis for a Bitcoin address, do not need to be generated randomly; instead, one can generate a Bitcoin address, fully compatible with Blockchain.info’s wallet and Armory, using nothing but standard easily available cryptographic tools and a password of your choice. If you ever lose access to your client or account, or if you are using a brain wallet and don’t ever store your wallet electronically or on paper at all, you can always fully recover the ability to use your address simply by repeating the procedure you used to create it with the same password.

The trick is a simple one: open this web page or this new tool by Ubaidullah Butt in a new tab in private browsing mode (Shift+Ctrl+N in Chrome and Shift+Ctrl+P in Firefox), turn off your internet connection for security reasons, input the password into the larger textbox at the top, hit “Calculate SHA-256 hash,” and copy it down somewhere. Close the tab, turn the internet back on, and follow your wallet’s instructions for importing your own private key. It just so happens that the output of the SHA256 hash function is in exactly the right format to be a private key under Bitcoin’s elliptic curve cryptography system. You don’t have to use online tools to find the SHA256 hash; on Linux, for example, the command

echo -n 'password' | sha256sum | grep -o '[0-9a-f]*'

does the same thing and is more secure.

However, while this is a convenient way of reliably generating addresses, it is important to be extremely careful when using it. Recently, a Bitcoin user attempted a dictionary attack against addresses generated in this way, generating addresses from millions of passwords found in a leaked password database from an unrelated source, and ended up randomly guessing the backdoor keys to addresses that, at their peak, contained a total of seven bitcoins. Of course, this sum is a small one, but as the number of Bitcoin users increases and alternative wallet generation strategies become more popular, it will only increase, and there will be more incentive for someone with access to greater computer power to attempt this feat once again. Given that Bitcoin mining companies are developing computers thousands of times faster and more efficient at the task of calculating SHA256 hashes than anything else available today, they will be able to get much further.

So, how can you protect yourself? The most basic option is to use a strong password, and not something like 12345678, to secure your private key. However, the stronger the password the harder it will be to both input and remember, so stronger passwords, while being a necessity, need to be complemented with other strategies. One option is to use a hash function deliberately designed to run slowly. One popular option is bcrypt, of which a single hash takes a few hundred milliseconds to calculate. The wait is an insignificant one when you’re trying to create or recover your address yourself, but becomes prohibitive to any attacker wishing to attempt hashes by the millions. The simplest implementation to use is python-bcrypt; after installing it, open a Python console, type

import bcrypt

followed by

x = bcrypt.hashpw ('password',bcrypt.encode_salt('0000000000000000',12))

(you can replace the empty salt with a second password if you wish). You will then need to apply SHA256 to the result to get the correct format for private key insertion, but what matters is that you have a very slow function forming the bulk of the generation process. Another possibility is to apply SHA256 a hundred thousand times (the python for which is

import hashlib

, followed by

x = 'password'

, then

for i in range(100000): x = hashlib.sha256(x).hexdigest()

and finally

print(x)

) or, for added security against specializing mining computers, apply SHA512 a hundred thousand times instead and then only take the first half of the output.

However, there is also another option. Consider how password authentication works for normal websites: logging in to one’s Google, Twitter or Bitcointalk account does not simply require typing in a password to authenticate yourself, you must type in a username as well. And for good reason, too – rather than being able to pull off a dictionary attack and make off with thousands of accounts in one fell swoop, attackers are forced to try every password in their dictionary for each and every username that they come across, and they may not even have the database of usernames to work with. The solution to the Bitcoin address cracking problem is thus to replicate the username/password model for your private key. Rather than hashing “password”, I might hash “vbuterin:password” instead. As long as you remember your username and don’t have a complex convention for stringing the two together, this doesn’t harm memorability at all, but does severely hamper an attacker’s ability to unlock your address for his own use.

Creating your own addresses deterministically from a password is a powerful feature, and has many unique and powerful uses. It allows you to use your Bitcoin wallet with the reassurance that, even if you lose everything you have, you will still be able to recover it. It allows you to use Bitcoin without relying on any software except at transaction time. Combined with other advanced elliptic curve mathematical techniques, it can also be used to generate complex hierarchical wallets with a root password. However, passwords have their risks, and when money is at stake, doubly so. For this reason, it is important to understand passwords’ limitations, and use them with a healthy dose of prudence.