Skip to content

Instantly share code, notes, and snippets.

@gavinandresen
Created March 27, 2012 16:54
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gavinandresen/2217885 to your computer and use it in GitHub Desktop.
Save gavinandresen/2217885 to your computer and use it in GitHub Desktop.
Bitcoin wallet and payment security, assuming a compromised device

I'm writing this to organize my thoughts on creating much more secure bitcoin wallets and payments.

Threat model

I assume the user starts with 2 uncompromised devices, and installs and configures trusted and uncompromised Bitcoin software for managing their wallet and confirming payments on both of them. I don't mean to imply that existing mechanisms for determining whether or not devices and software are uncompromised are sufficient, just that the problem of creating a secure starting state is outside the scope of what I want to consider in this document.

I assume that at some point after initial setup one of the devices is compromised by malware that has full access to the machine, including replacing any applications (bitcoin.exe, the user's web browser, etc), reading memory and/or altering the information displayed to the user.

The goal is to design protocols such that the user's wallet and payments are as secure as possible.

Authorization: Did you initiate this payment?

Bitcoin supports multisignature transactions, with signatures from more than one key required to spend coins (where "coin" is really "an unspent output from a previous transaction"). 2-keys-required transactions can be used so that even if an attacker completely compromises one device they cannot spend coins without either compromising or getting authorization from the second device (which holds the second key).

How the keys are generated on each of the devices, how the devices exchange public keys so multisignature bitcoin addresses can be created to fund the wallet, when and how they're backed up, etc. are important implementation details that I'm going to ignore in this document.

Authentication: Who is being paid?

Today, payments are made via bitcoin addresses. However, under the threat model described above, how can a user verify that a bitcoin address that they get from a web page, email message, or sms actually belongs to the person or organization that they are trying to pay?

If their device is compromised, then they cannot trust (but may not yet know that they cannot trust) any information that is displayed on the device. That implies that there must be some off-the-device mechanism for verifying who is being paid.

If the who is nothing but a bitcoin address, then most users will almost certainly not bother with an off-the-device verification. And if the amount of the transaction is small, then that is a reasonable tradeoff; they will figure out that their device is compromised the second or third time they send a transaction and the recipient complains that they never got it.

If the who is not a bitcoin address but a persistent, well-known identity like "amazon.com" or "gavinandresen@gmail.com" or an IIBAN identifier or a trusted gpg key then the problem is getting the uncompromised device to validate that the payment is going to the person or organization with that identifier.

See BIP15 for a proposal for payment 'aliases'.

Non-repudiation: "that's not MY address, you must be compromised!"

Another threat is that the person or organization being paid falsely claims that they did not receive payment because you sent bitcoins to an address that doesn't belong to them.

All together now

Here's a straw-man proposal, imagining that the user is paying for something on Amazon.com using a possibly-compromised computer and their cell-phone (as the second, assumed-to-be-uncompromised device).

  1. Amazon.com's checkout process includes a link to Pay With Bitcoin on a page secured with SSL (https://www.amazon.com/...etc). The payment information is digitally signed with an x.509 certificate rooted at a trusted-by-both-devices certificate authority. The payment information includes the bitcoin address to receive payment, the amount, name (which must match the name in the certificate), and a timestamp.
  2. Clicking on the link launches/opens a bitcoin client running on their (possibly compromised) computer.
  3. The bitcoin client verifies the signature on the payment information by validating the certificate and signature, checking the certificate status using OCSP (Online Certificate Status Protocol), then asks the user to authorize the transaction.
  4. If the user authorizes, then the client creates a transaction, provides half the signatures needed, and forwards it along with all of the signed payment information to an app running on the cell-phone for second-device authorization.
  5. The cell-phone app repeats the validation and authorization, independently validating the certificate and checking the signature, then asking the user to authorize the transaction.
  6. Assuming the user authorizes the transaction, the remaining signatures are generated and payment is complete.
  7. The signed payment information and certificate used for signing should be retained along with the transaction ID as proof of payment.

The same general protocol should work for other identity systems. For example, for individuals with pgp keys, the pgp web-of-trust system could be used, with the transaction pgp-signed and then each device independently querying a keyserver or keyservers to validate pgp-signed transaction information and evaluate the trustworthiness of the signature. IIBAN identifiers might be validated with a central trusted server that maintains a mapping of IIBAN identifier to organization, etc.

But... but...

All of the above assumes that the identity system is secure. If the attacker can get the user to go to a look-alike URL that they control (amaz0n.com perhaps) and for which they have a valid, certificate-authority-signed certificate then they win. We should work with organizations like the Anti Phishing Working Group and incorporate techniques like blacklists of known phishing look-alikes to warn users whenever possible that they might not be paying who they think they are paying.

I also imagine that for small-value, person-to-person transactions bitcoin addresses will continue to be widely used; educating users of the risks should be part of the secondary authorization process if a large-value, unsigned (bitcoin-address-only) transaction is being authorized.

TODO

  • Extend the BIP21 URI syntax to support a payment-information-covering signature.
  • Implement multi-device/multisignature wallets and protocols for setting them up and then authorizing payments.
  • Work through the details; for example, it it practical for PHP/Python/Ruby/whatever code running on a web server to call openssl to sign payment information before it is displayed on a web page? It should be pretty easy to put together a working prototype using openssl.

Possibly useful links

DKIM : Perhaps adapt as the format for the bitcoin: URI extension? Or could we leverage it to authenticate person-to-person transactions?

Proposal for "Signed Aliases" : From ThomasV, Electrum client developer

Sipa's payment protocol proposal

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