Bitcoin Forum
May 04, 2024, 02:20:48 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1] 2 3 4 »  All
  Print  
Author Topic: [PULL] Wallet Private Key Encryption  (Read 16634 times)
Matt Corallo (OP)
Hero Member
*****
expert
Offline Offline

Activity: 755
Merit: 515


View Profile
May 17, 2011, 11:34:29 PM
Last edit: June 27, 2011, 01:06:11 AM by Matt Corallo
 #1

I suppose the title speaks for itself, but here is the commit blurb:
Quote
Add wallet privkey encryption.

This commit adds support for ckeys, or enCrypted private keys, to the wallet.
All keys are stored in memory in their encrypted form and thus the passphrase
is required from the user to spend coins, or to create new addresses.

Keys are encrypted with AES-256-CBC through OpenSSL's EVP library. The key is
calculated via EVP_BytesToKey using AES256 with (by default) 1000 rounds and
a random salt.

By default, the user's wallet remains unencrypted until they call the RPC
command encryptwallet <password> or, from the GUI menu, Options->
Encrypt Wallet.

When the user is attempting to call RPC functions which require the password
to unlock the wallet, an error will be returned unless they call
walletpassword <password> <time to keep key in memory> first.

A keypoolrefill command has been added which tops up the users keypool
(requiring the password via walletpassword first).
keypoolsize has been added to the output of getinfo to show the user the
number of keys left before they need to specify their password and call
topupkeypool.

A walletpasswordchange <oldpassword> <newpassword> has been added to allow
the user to change their password via RPC.

Whenever keying material (unencrypted private keys, the user's password, the
wallet's AES key) is stored unencrypted in memory, any reasonable attempt is
made to mlock/VirtualLock that memory before storing the keying material.
This is not true in several (commented) cases where mlock/VirtualLocking the
memory is not possible.

Although encryption of private keys in memory can be very useful on desktop
systems (as some small amount of protection against stupid viruses), on an
RPC server, the password is entered fairly insecurely. Thus, the only main
advantage encryption has for RPC servers is for RPC servers that do not spend
coins, except in rare cases, eg. a webserver of a merchant which only receives
payment except for cases of manual intervention.

Thanks to jgarzik for the original patch and sipa for all his input.

Pull request is at https://github.com/bitcoin/bitcoin/pull/232
https://github.com/bitcoin/bitcoin/pull/352
Now rebased on wallet class + mostly based off of Pieter's suggested model.

EDIT: New commit blurb to match changes.

Bitcoin Core, rust-lightning, http://bitcoinfibre.org etc.
PGP ID: 07DF 3E57 A548 CCFB 7530  7091 89BB B866 3E2E65CE
1714832448
Hero Member
*
Offline Offline

Posts: 1714832448

View Profile Personal Message (Offline)

Ignore
1714832448
Reply with quote  #2

1714832448
Report to moderator
1714832448
Hero Member
*
Offline Offline

Posts: 1714832448

View Profile Personal Message (Offline)

Ignore
1714832448
Reply with quote  #2

1714832448
Report to moderator
1714832448
Hero Member
*
Offline Offline

Posts: 1714832448

View Profile Personal Message (Offline)

Ignore
1714832448
Reply with quote  #2

1714832448
Report to moderator
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1714832448
Hero Member
*
Offline Offline

Posts: 1714832448

View Profile Personal Message (Offline)

Ignore
1714832448
Reply with quote  #2

1714832448
Report to moderator
Gavin Andresen
Legendary
*
qt
Offline Offline

Activity: 1652
Merit: 2216


Chief Scientist


View Profile WWW
May 18, 2011, 12:15:01 AM
 #2

Random thought RE: passwords and RPC:

I was thinking a better way of handling the password might be a new RPC command:

walletpassword <password> <timeout>

... which would store <password> in memory for <timeout> seconds.  If you know your server is secure, you'd give a very long <timeout> at startup.

That same <timeout> mechanism might be very handy in the GUI (somebody who knows more about password security might have something intelligent to say about the tradeoff between the risk of storing hashed-password in memory versus the convenience of not having to constantly re-enter it).

A walletpasswordchange <oldpassword> <newpassword> seems like it would be very handy, too.

Tacking <password> onto the beginning of RPC argument lists seems like the wrong thing to do.

How often do you get the chance to work on a potentially world-changing project?
Matt Corallo (OP)
Hero Member
*****
expert
Offline Offline

Activity: 755
Merit: 515


View Profile
May 18, 2011, 12:22:06 AM
 #3

walletpassword <password> <timeout>

... which would store <password> in memory for <timeout> seconds.  If you know your server is secure, you'd give a very long <timeout> at startup.
Ah, good idea.  Hadn't really given any real thought towards RPC stuff, just kind of did it, I suppose just doing it at 1 AM is never the right approach.  The fact that that that fits perfectly with the current method of password handling is also quite nice Smiley.

Bitcoin Core, rust-lightning, http://bitcoinfibre.org etc.
PGP ID: 07DF 3E57 A548 CCFB 7530  7091 89BB B866 3E2E65CE
Matt Corallo (OP)
Hero Member
*****
expert
Offline Offline

Activity: 755
Merit: 515


View Profile
May 18, 2011, 11:37:29 AM
 #4

walletpassword <password> <timeout>
A walletpasswordchange <oldpassword> <newpassword> seems like it would be very handy, too.
Added, committed, rebased, pushed.

Bitcoin Core, rust-lightning, http://bitcoinfibre.org etc.
PGP ID: 07DF 3E57 A548 CCFB 7530  7091 89BB B866 3E2E65CE
khal
Hero Member
*****
Offline Offline

Activity: 540
Merit: 500



View Profile WWW
May 18, 2011, 12:05:15 PM
 #5

I would suggest :
Quote
walletpassword <timeout> [password]

If password is not on the command line, bitcoin will prompt for it. This will avoid your password to be stored in history files (or anything else) and still allow putting all in 1 command if you prefer. Same for walletpasswordchange rpc.
Pieter Wuille
Legendary
*
qt
Offline Offline

Activity: 1072
Merit: 1174


View Profile WWW
May 18, 2011, 12:29:29 PM
 #6

I'd like to see a way to pass the passphrase through a file descriptor instead of on the command-line, so it isn't visible on the process list.

I do Bitcoin stuff.
Gavin Andresen
Legendary
*
qt
Offline Offline

Activity: 1652
Merit: 2216


Chief Scientist


View Profile WWW
May 18, 2011, 01:05:49 PM
 #7

Would it be good enough if I volunteered to write a little perl or python or php or bash script that reads the passphrase from a file descriptor and then posts the right JSON-HTTP request?

If the consensus is to teach bitcoind to read arguments from file descriptors, somebody please figure out if there's a standard for how other unix apps do that.  Here's what curl does:
Quote
If you start the data with the letter @, the rest should be a file name to read the data from, or - if you want curl to read the data from stdin.

How often do you get the chance to work on a potentially world-changing project?
Matt Corallo (OP)
Hero Member
*****
expert
Offline Offline

Activity: 755
Merit: 515


View Profile
May 18, 2011, 01:32:05 PM
 #8

This will avoid your password to be stored in history files
If you dont want something in .bash_history (probably works for others too) you can just prefix the command with a space.
Doesn't mean the point isn't valid but still...

Bitcoin Core, rust-lightning, http://bitcoinfibre.org etc.
PGP ID: 07DF 3E57 A548 CCFB 7530  7091 89BB B866 3E2E65CE
Luke-Jr
Legendary
*
expert
Offline Offline

Activity: 2576
Merit: 1186



View Profile
May 18, 2011, 01:34:32 PM
 #9

This will avoid your password to be stored in history files
If you dont want something in .bash_history (probably works for others too) you can just prefix the command with a space.
Doesn't mean the point isn't valid but still...
It will still show up on the process list ('ps aux') at least for some duration.

I would be concerned with the timeout mechanism creating a race condition. A virus/trojan is going to be able to spend the coins faster than the user. But I guess it could just be added to the already-long list of JSON-RPC problems to be addressed by any contending protocol.

Matt Corallo (OP)
Hero Member
*****
expert
Offline Offline

Activity: 755
Merit: 515


View Profile
May 18, 2011, 01:39:10 PM
 #10

It will still show up on the process list ('ps aux') at least for some duration.
Hence the "Doesn't mean the point isn't valid but still..."

I would be concerned with the timeout mechanism creating a race condition. A virus/trojan is going to be able to spend the coins faster than the user. But I guess it could just be added to the already-long list of JSON-RPC problems to be addressed by any contending protocol.
If you are concerned about getting the security that tight, there are way more pressing problems.  Memory dumping bitcoin, replacing the bitcoin binary which makes the rpc calls, etc, etc, etc.  But yea, you would have to enter password the way they were originally, and I agree with gavin, that is not nearly as good.

Bitcoin Core, rust-lightning, http://bitcoinfibre.org etc.
PGP ID: 07DF 3E57 A548 CCFB 7530  7091 89BB B866 3E2E65CE
xf2_org
Member
**
Offline Offline

Activity: 98
Merit: 13


View Profile
May 18, 2011, 04:21:43 PM
 #11

If the consensus is to teach bitcoind to read arguments from file descriptors, somebody please figure out if there's a standard for how other unix apps do that.

What you're talking about is a bitcoin shell, IMO.  Just read commands from standard input, like /usr/bin/mysql or /usr/bin/sqlite3.

tcatm has already put some thought and code towards this, and I like this approach.  See https://github.com/tcatm/bitcoin/tree/cli and http://forum.bitcoin.org/index.php?topic=6110.0
Matt Corallo (OP)
Hero Member
*****
expert
Offline Offline

Activity: 755
Merit: 515


View Profile
May 18, 2011, 05:57:35 PM
 #12

What you're talking about is a bitcoin shell, IMO.  Just read commands from standard input, like /usr/bin/mysql or /usr/bin/sqlite3.
I agree here, making RPC Password entry more secure falls out of the scope of this patch as it requires significant changes to the way RPC is currently handled, which IMHO should not be done here.  (only partially because I'm lazy)
I agree password entry could be more secure via RPC (and GUI for that matter), but the largest target here are really merchants who need a bitcoind to receive money without needing to spend it except for manual intervention.  Here they can pre-generate a couple thousand keys for the pool, and then not have to worry except for when the pool gets low, if their server is compromised, they still don't get their bitcoins.  For GUI users, its nice as it allows them to not have to worry as much about viruses and the like stealing their wallet, but at the end of the day, making a popup that looks identical to Bitcoin asking for their password or reading Bitcon's memory while the user is entering their password is not all that hard. 
For merchants who need this kind of security, they wont be entering their password on a compromised machine anyway (I'd hope) and if they are all hope is lost anyway. 

Bitcoin Core, rust-lightning, http://bitcoinfibre.org etc.
PGP ID: 07DF 3E57 A548 CCFB 7530  7091 89BB B866 3E2E65CE
khal
Hero Member
*****
Offline Offline

Activity: 540
Merit: 500



View Profile WWW
May 18, 2011, 08:09:50 PM
 #13

You annoy people for potential security problems that are 100'000 x less frequent than infected/zombie computers and you hope people "wont be entering their password on a compromised machine" ? Are you really serious, guy ?
Matt Corallo (OP)
Hero Member
*****
expert
Offline Offline

Activity: 755
Merit: 515


View Profile
May 18, 2011, 08:56:22 PM
 #14

You annoy people
Im not sure what you mean by annoy here, the patch requires people to enter the password on send, how is that anoying?
for potential security problems that are 100'000 x less frequent than infected/zombie computers
Again, not really sure what you mean here.  I'm assuming you mean memory stealing? or what?
We have already seen bitcoin wallet-stealing trojans.
and you hope people "wont be entering their password on a compromised machine" ? Are you really serious, guy ?
What is wrong with that hope? This was specifically in reference to people sending from servers, not clients.  Obviously clients will be, but not holding the keys except for milliseconds while they are being entered should be able to stop most basic viruses from stealing them.  That would mean that someone has to spend real time writing the virus/trojan examining memory layout and such of different bitcoin builds or atleast knowing a pretty large amount about the inner workins of wx+bitcoin.
In the case of servers, I'd hope that even if the server is compromised, the remote RPC client will not be run on the server and also, I'd hope the the merchant can find out that they have been compromised before they enter their password to send coins.

Bitcoin Core, rust-lightning, http://bitcoinfibre.org etc.
PGP ID: 07DF 3E57 A548 CCFB 7530  7091 89BB B866 3E2E65CE
doublec
Legendary
*
Offline Offline

Activity: 1078
Merit: 1005


View Profile
May 23, 2011, 06:28:17 AM
 #15

I don't understand the topupkeypool command. Can you explain why it is needed, and how the user is supposed to know to run it. What happens if they don't and the keypool (whatever that is) runs out?
Matt Corallo (OP)
Hero Member
*****
expert
Offline Offline

Activity: 755
Merit: 515


View Profile
May 24, 2011, 02:11:24 AM
 #16

I don't understand the topupkeypool command. Can you explain why it is needed, and how the user is supposed to know to run it. What happens if they don't and the keypool (whatever that is) runs out?
For users running with encryption disabled, it is not needed (as it is currently).  Bitcoin will top up the keypool all the time and it should always be full.
For users running with encryption, the password is required to add new keys to the wallet.  Thus the user needs to manually top up their key pool (otherwise it happens automatically when they enter their password to send coins or otherwise).  Thus for most users, it is not really required that they keep track of the keypool and top it up (except when backing up).  Bitcoin handles new keys when keypool is out pretty well.  For mining and change return, it uses the default address.  When a new tx is received on the client's address, no new address is generated.

Bitcoin Core, rust-lightning, http://bitcoinfibre.org etc.
PGP ID: 07DF 3E57 A548 CCFB 7530  7091 89BB B866 3E2E65CE
thefiatfreezone
Newbie
*
Offline Offline

Activity: 30
Merit: 0


View Profile WWW
May 31, 2011, 08:50:20 AM
 #17

What would it take to put in separate passwords for each wallet 'account'?
So that for multiple user systems each user can access their own account details and functionality without affecting or having access to others accounts.

And yes, with the ability to put in a 'master' password for global wallet access?
cloud9
Member
**
Offline Offline

Activity: 126
Merit: 10


View Profile
May 31, 2011, 08:59:08 AM
 #18

Can Private keys from a wallet be extracted and imported individually from a wallet?  That may make BTC web deployment more mobile as you would be able to cart your keys along from one web BTC client provider to another.

twmz
Hero Member
*****
Offline Offline

Activity: 737
Merit: 500



View Profile
June 03, 2011, 06:13:47 PM
 #19

I have been running this patch for the past few days on a headless bitcoind with a custom web based GUI that uses the JSON-RPC (remotely over SSL) and it has worked very well without any functional problems.  Well done.  I think this change is excellent and really addresses a key concern with protecting wallet.dat.

The only minor thing that I noticed you might want to fix is that the walletpasswordchange RPC method was not added to the RPC help results.

Was I helpful?  1TwmzX1wBxNF2qtAJRhdKmi2WyLZ5VHRs
WoT, GPG

Bitrated user: ewal.
Matt Corallo (OP)
Hero Member
*****
expert
Offline Offline

Activity: 755
Merit: 515


View Profile
June 03, 2011, 08:42:37 PM
 #20

The only minor thing that I noticed you might want to fix is that the walletpasswordchange RPC method was not added to the RPC help results.
Thanks fixed that and fixed some minor logic issues to make it a bit cleaner for -nocrypt.

Bitcoin Core, rust-lightning, http://bitcoinfibre.org etc.
PGP ID: 07DF 3E57 A548 CCFB 7530  7091 89BB B866 3E2E65CE
Pages: [1] 2 3 4 »  All
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!