Skip to content

Instantly share code, notes, and snippets.

@gavinandresen
Created January 30, 2011 19:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save gavinandresen/803170 to your computer and use it in GitHub Desktop.
Save gavinandresen/803170 to your computer and use it in GitHub Desktop.
Thoughts on bitcoin wallet encryption
KEPT FOR REFERENCE: Optional encryption of private keys was implemented starting with Bitcoin version 0.4.
Design notes on what an ideal wallet encryption feature for Bitcoin would look like:
Encrypt only the important information-- the private keys needed to spend coins (sign transactions).
Decrypt only when a key is needed to sign a transaction (on a send).
I don't think encrypting the public keys, transactions/comments is worth it, but that might be
debatable. If only the private keys are encrypted, then somebody stealing your wallet CAN violate
your privacy and find out the balance of bitcoins in that wallet and see all transactions to/from
that wallet. If encrypting the public keys/transactions is desired, then I think that should be
done as a separate password (it will have to be entered every time bitcoin starts) and as a
second project.
The Mac has a standard way of storing passwords (the KeyChain). Are there equivalents for
Windows/Linux? Bitcoin shouldn't reinvent the wheel, but should leverage the system's standard
way of storing/sharing/backing up/recovering passwords.
Changing passwords has to work.
This use case should work:
+ Set password
+ Backup wallet
+ ... time passes...
+ Change password
+ ... time passes, wallet gets (partially, maybe) corrupted...
+ Restore/import backed up wallet : Must be able to enter old password to recover, but old
keys should be re-encrypted with new password.
JSON-RPC sendtoaddress/sendfrom commands will need an (optional) password param.
Idea from dirtyfilthy in IRC chat: If private keys are encrypted using a public key,
then generating new ones and encrypting them doesn't require user to enter their password
(only using them to spend would). That's important because of the way the bitcoin keypool works.
However, that does open up another possible attack: can write public/private keypairs into your
wallet without your password, and you'll eventually use the attacker's keys (and they can spend
the coins behind your back).
@mgiuca
Copy link

mgiuca commented Feb 18, 2011

It sounds like it will not be possible to allow asymmetric encryption (since write protection is as important as read protection).

The public/private keypairs are generated 100 keys in advance, right? It seems to me that they are only consumed in two situations: 1. When sending money (it consumes one of the keys as the "change" account), and 2. When you click "new address".

Couldn't you just make it so they are only generated when sending money? So the user enters the passphrase when sending, and at the same time, the system takes the opportunity to generate as many new keys are required to get ahead 100.

This means each time you click "new address", it consumes a key without generating a new one. Oh well, there are 100. Maybe when it gets down to 50, it could prompt the user for a passphrase so it can generate 50 more. Whenever you send money, however, it generates all the required keys, so as long as you send money once per 50 addresses you manually generate, you don't ever need to enter your passphrase except when sending money.

@mgiuca
Copy link

mgiuca commented Mar 6, 2011

@fnordsoft but I think the problem the "gist" is trying to avoid is that you don't want the user to have to enter their private key or asymmetric key password every time a new address is added to the wallet. Signing the private keys would require that the user enters some passphrase (which could be an asymmetric key or a passphrase on another private key) -- if you don't ask the user for a passphrase then it means the key you are using to sign is stored in the clear.

@genjix
Copy link

genjix commented Mar 9, 2011

erm, no. With asymmetric encryption, you would decrypt the wallet once using a passphrase at startup into memory. You only then need the public key to encrypt your wallet on shutdown.

@mgiuca
Copy link

mgiuca commented Mar 9, 2011

Well, yes, but the whole point of the original gist was that you didn't necessarily want to prompt the user for a passphrase on startup, only when sending money.

Also, encrypting the wallet only on shutdown seems like a bad idea -- it implies that the wallet will not be stored on disk at all until the program is closed, so a crash could lose any new keys generated while the program is running. The wallet should be written whenever a new key is generated. Therefore, if asymmetric encryption is used, the public key will be required whenever that happens. Now while public keys don't necessarily need to be password-protected, as Gavin originally pointed out, you do need some kind of signing as well or bad guys can write their own keys to your wallet. Therefore, you would need both the public and private key whenever a new key is generated. Alternatively, if using symmetric encryption (and you might as well be, since you need both the public and private key you aren't getting any benefit from asymmetric encryption), you would need the encryption key whenever a new key is generated.

@genjix
Copy link

genjix commented Mar 9, 2011

I think the current wallet DB, decrypts into memory :) We can decrypt once and not to disk (although I'll do it to a temp file first in early versions).

@mgiuca
Copy link

mgiuca commented Mar 9, 2011

What? It isn't encrypted on disk... if it was you would need to provide a passphrase to decrypt it. (You can dump the contents of your wallet human-readable with bitcointools without a passphrase, so it can't be encrypted.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment