Skip to content

Instantly share code, notes, and snippets.

@gavinandresen
Last active September 2, 2023 13:18
Show Gist options
  • Save gavinandresen/5616606 to your computer and use it in GitHub Desktop.
Save gavinandresen/5616606 to your computer and use it in GitHub Desktop.
Yubikey/Google Authenticator protected Bitcoin Wallets

Thumbnail sketch: Two-factor (Yubikey or Google Authenticator) protected wallets

Hardware:

Computer. Shared-secret authenticator (Yubikey/Google Authenticator/etc). Server (possibly shared with millions of other users).

Motivating use case setup:

User creates a split (2-of-2 multisig) wallet on the computer and server. Keys must be securely backed up to protect against loss. GUI to be determined, but there will be some type of "Use Authenticator" checkbox specified at setup.

User also arranges for the server to know the shared secret with the shared-secret authenticator.

Motivating use case, usage:

Coins are sent into the wallet via P2SH 2-of-2 address(es).

On spend, user is prompted for authenticator one-time-password (OTP). One-time-password and half-signed transactions are sent to the server. If OTP is correct, second signature is created and payment is made immediately, with no further interaction required(*). If incorrect, no payment made (server should inform user of the invalid payment attempt via email/sms/carrier pigeon).

(*) server might offer to further validate high-value transactions via SMS or DNA sample submission or some other authentication method. And server might enforce rules to limit BTC sent per 24-hours or have other protections.

Attacks:

  1. Attacker steals computer / private keys, but does not have authenticator device and does not compromise server. Coins are safe.
  2. Attacker compromises my computer, installs malware (e.g. keylogger, or replaces client binary). Use of OTP authenticator limits loss of coins to whatever mitigation policy is in place on the server.
  3. Attacker compromises server. Coins are safe.
  4. Attacker compromises computer and server. Coins are lost, because both keys are compromised.
  5. Man-in-the-middle between computer and server. Coins are safe, attacker may DoS (prevent spending).
@aantonop
Copy link

Great suggestion

Combine this with BIP0032, to deterministically derive two chains, one for the user sigs, one for the authentication server signatures, both derived from a master key backed up on a hardware or paper wallet and encrypted by BIP0038.

This way, the user can create the master, derive two key chains and submit one extended private key to an authentication server with a policy, keeping the other in a private wallet. Master key is the backup for both chains.

@gavinandresen
Copy link
Author

@apetersson: grazcoin/ubtcbank project ? The tricky bit is standardizing the network protocol for setup / spending.

@BitcoinAdvisory: network connection between wallet and server could be a p2p network, but just using https would be much simpler. You have to trust the server not to disclose private keys and to keep attackers out, so you won't be trusting a random p2p node to be a server for you.

@KeyvanJS: yes, if the server is offline you cannot spend. I'm imagining competing "wallet protection services" that aim for close to 100% uptime (redundant servers, etc).

@aantonop: Excellent idea. The other tricky bit with all this is making backups easy and convenient enough to prevent "I forgot my password / I lost my keys" .

@gavinandresen
Copy link
Author

@super3 : RE: road map for Bitcoin-Qt:

Finish payment protocol, because it is much better (user-friendly AND secure) to get a SMS that says "authorize payment of 0.11 BTC to foo.com?" rather than "authorize payment of 0.11 BTC to 1qr77WVCxoJkTe5f61m2sd2KY6jvQFut4 ?"

Then wallet needs to be rewritten to support BIP32 and the notion of multi-signature addresses. We want to remove our Berkeley DB dependency when this is done, too.

And GUI and network code to support talking to a wallet protection service to do setup and then spending, with thought given to what happens if the wallet protection service goes out of business or is unreliable.

@ashleyholman
Copy link

"3. Attacker compromises server. Coins are safe."

What if the attack on the server resulted in loss of keys, would that mean lost coins, or does the user also have a copy of the server's private key? If the server was offline for some time, could peoples money become unspendable for that period?

What about having a 1+1-of-N scheme where the user's key is always required, but you could have more than one server if you wanted to reduce the risk of a server being unable to sign a transaction?

@petertodd
Copy link

@KeyvanJS There's another way to do this that doesn't require a third-party or a second device, and results in smaller transactions too: http://www.mail-archive.com/[email protected]/msg02601.html Basically from the users point of view their wallet is split into savings and spending, and to move funds from savings to spending you need a short authorization code, either generated on your phone or pre-printed on a sheet of paper. You know how much you're spending because each code only authorizes a certain amount of BTC, say 1BTC per code, and without the code it's impossible for the savings to be spent. On the other hand, the balance in your spending wallet isn't being protected - it can be spent by an attacker who has hacked your computer.

Note that neither solution by itself solves the problem of moving funds to your wallet securely, although with my way at least you can safely have an app on your phone co-operate with your computer wallet to jointly sign a payment request with your address. Gavin's way can do something similar, but would be more along the lines of having the "wallet security provider" vouch for your identity, and maybe they'd send a text message to your phone or something to make sure you know where the funds are going.

@vbuterin
Copy link

I applaud the initiative, but 2-of-2 is a bad idea IMO. Generally, loss is a considerably worse problem in unmanaged systems like Bitcoin than theft. What we really need is 2-of-3. The way I envision that is a 2-of-3 between a computer wallet, a centralized service and a brainwallet or printed wallet - or even another centralized service like email.

@timohanke
Copy link

@vbuterin I assume the user will keep a (paper) copy of both secret keys, but only has to access one electronically when spending, the other one is accessed by the server.

@Suffice
Copy link

Suffice commented Jul 28, 2013

People would be expected to backup the second key somewhere, or else risk forever being locked out of their wallet.

My only worry is how to create a wallet on an already compromised machine without the risk of having the first and second key also compromised upon creation. It seems like it would only give a false sense of security to some.

@bitnukl
Copy link

bitnukl commented Jul 29, 2013

Why not simply create a 2-of-2 wallet and transfer one private key onto a mobile phone. That's much easier to implement and we don't need a kind of central server for this solution.
It's a nice idea but until we can use 2-of-2 wallets with most clients, it sounds more like a stretch goal for me.

@scryb3
Copy link

scryb3 commented Aug 5, 2013

Agreed, the whole Server and OTP infrastructure are added complexity. The second "factor" of authentication is the second private key, the OTP is just used to authorize a third party to use it with a shorter challenge/response.

ANY use of 2-of-2 (or 2-of-3, etc) can be considered "2-factor" and exposes the core challenge of securely creating, transmitting, storing and accessing these keys. What is really needed is a secure handshake for the 2 devices (whether mobile, desktop, or server based) right?

I've been wondering whether the BIP32 HD Wallet might be of use here? Using 2 (or more) keys with a common parent (or grandparent?) would make generating the m-of-n address easy, but would it be easy to secure?

@mquandalle
Copy link

Bitcoin Authenticator - 2FA for wallets: https://www.youtube.com/watch?v=-EKgFktOoWY

@starwalkerz
Copy link

Could something like Cinder provide storage for the keys? StorjX is a coin that tries to do something similar. https://wiki.openstack.org/wiki/Cinder

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