5
$\begingroup$

I'm building a bitcoin web application that will require all users to be assigned a wallet for adding funds to their account. I plan on exposing the public key to the user (the bitcoin address). Users will simply use their exchange or their bitcoin client to send money to this address and their accounts will be subsequently credited.

I'm wondering what the best method would be for storage of each wallet's private key. Obviously, the web application needs to know it when the user wants to spend the coins. However, in the event of a database breach, the attacker could obviously steal everyone's private keys, and therefore, their money.

Here is my idea and I would like some feedback whether or not it is secure:

I am already using phpass which utilizes bcrypt to salt and hash their password on signup. When a signup occurs, generate a bitcoin key pair, and (MCRYPT_RIJNDAEL_256) encode the private key using the user's password as the encryption key.

Now when users are willing to spend their coins, I simply re-ask them for their password to uncover their private key to the web application. This is a small price to pay for the added security.

If the database is ever breached, the attacker would only see bcrypted passwords and MCRYPT_RIJNDAEL_256 encoded private keys to which he does not know the decryption key.

Update 1: I suppose the public key should also follow the same algos as the private key because a database attacker could replace the public key with one of his own unbeknownst to the user.

By the way, I've already asked this question on Bitcoin Beta SE but with much less emphasis on the specifics and more of just a general best practice question.

$\endgroup$
4
  • $\begingroup$ What's your plan if they forget their password? $\endgroup$ Aug 27, 2012 at 3:28
  • $\begingroup$ They can have a password reset link sent to their email address. $\endgroup$ Aug 27, 2012 at 3:57
  • 1
    $\begingroup$ Ahh, I see why you asked now. Even if I provide them with the ability to create a new password, their coins will still be lost forever... I could send their initial password to their email address on signup so they have a permanent copy. And also on "Change Password Requests" email it to them then as well. Just thinking out loud here. Would like to hear any recommendations. $\endgroup$ Aug 27, 2012 at 4:07
  • 1
    $\begingroup$ I don't know how many green addresses there are, but it might be worth it for your application to offer one. $\endgroup$
    – user991
    Aug 28, 2012 at 6:01

1 Answer 1

4
$\begingroup$

About the best you can do is have a master public/private key pair where the public key is stored on your server and the private key is stored offline. When you generate a new private key, encrypt it with the master public key and store that in the database. That way, if a password is ever lost, you can recover the user's private key by using the master private key to decrypt their encrypted private key.

$\endgroup$
6
  • $\begingroup$ This works great for password recovery, but not so well for spending coins. The web application will need to decrypt their encrypted private key any time coins wish to be spent. Therefore the master private key cannot be kept offline; it will have to be used every spending transaction. Am I understanding this right? $\endgroup$ Aug 27, 2012 at 5:41
  • 1
    $\begingroup$ No. For a spending transaction, you use the user's password to decrypt the private key. The master private key is only used if the password is lost. (This is the recovery mechanism, not the normal mechanism.) $\endgroup$ Aug 27, 2012 at 6:30
  • 1
    $\begingroup$ @JordanArseno For spending the coins you use a smaller hot wallet. There is no reason to have users spend their own coins. $\endgroup$ Aug 27, 2012 at 9:46
  • $\begingroup$ @DavidSchwartz: How can I use the user's password to decrypt their private key when their private key was encrypted using the master public key as you've said? (at)CodeInChaos - can you elaborate on this a bit? Wouldn't a smaller hot wallet mean users couldn't spend their accounts in full? $\endgroup$ Aug 27, 2012 at 13:43
  • 1
    $\begingroup$ Encrypt the private key with the user's password so that you can decrypt it with the password. The encryption with the master public key is only used if the user's password is lost. $\endgroup$ Aug 27, 2012 at 13:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.