Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: thanke on December 12, 2012, 09:55:10 PM



Title: [PROPOSAL] Secure Payment Protocol
Post by: thanke on December 12, 2012, 09:55:10 PM
We would like to propose a payment protocol with a lot of interesting features:
Homomorphic Payment Addresses and the Pay-to-Contract Protocol (http://arxiv.org/abs/1212.3257)

This could be of interest to the current ongoing development of hardware wallets as well as to the implementation of deterministic wallets.

[EDIT] Related thread: Destination Address Anonymization in Bitcoin (https://bitcointalk.org/index.php?topic=98737) [/EDIT]


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: jgarzik on December 12, 2012, 10:24:00 PM
A payment protocol is already being developed, with input from several on the bitcoin-development SourceForge mailing list.

See https://github.com/gavinandresen/paymentrequest for software or the mailing list discussion archives http://comments.gmane.org/gmane.comp.bitcoin.devel/1574



Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: Mike Hearn on December 13, 2012, 12:01:37 AM
Thanks for the thorough and high quality paper. I only had time to scan read it (nearly 1am here) and might take a closer look later. Hopefully others can comment.

My primary thought having scan read it is that your system is a lot more complex than the one we're developing, because of the assumption that the merchants web server should not have signing keys:

Quote
For M, however, this means that signing the bill can not be done on W

But that's not a normal assumption - the web server already needs the private keys to set up SSL sessions.

The only purpose SSL keys have in our current spec is to ensure that 2nd factors can display a human-meaningful identity, to avoid substitution attacks on compromised end-user machines. Dealing with compromised web servers is not in-scope for the current work because if a server is broken into and its SSL keys stolen, the hacker can as well switch out (some of) the addresses it's vending to their own. That's easier than using the stolen keys to sign fake bills and try and trick users into paying them, seeing as users would only confirm the payment if they were actually intending to pay that merchant anyway.

In our current spec, a "receipt" (proof of payment) is simply a signed payment request plus the transactions that paid the requested amount to the requested keys and the merkle branches linking them to the best chain.

Being able to "tear off" parts of a receipt is indeed useful, I was thinking about it the other day in a different context. But structuring the payment request as a merkle tree is overly complex, in my view. It's simpler for merchants to just provide a few different signatures that cover different parts of the structure, eg, one signature for everything, another signature that covers just the requested outputs.


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: Gavin Andresen on December 13, 2012, 03:28:02 AM
Wow, great paper!

I like the idea of the "bill" (aka contract aka "PaymentRequest") determining the payment address, and the merchant's private bitcoin-signing key or keys being stored off their web server.

I'll append some half-baked thoughts below on melding the current PaymentRequest proposal with your ideas.

Using a Merkle tree to reveal (or not) parts of the bill is a nifty idea, but I think that is orthogonal to the payment protocol, and could be a generic way of encoding any document. I tend to agree with Mike, it feels like a complex solution to something that really isn't a problem right now (maybe if we ever have CyberCourts to adjudicate disputes between anonymous customers and merchants it will be useful).

PS: I was amused by:
Code:
An implementation with bitcoin would require little effort.
Writing the code should be fairly straightforward; getting everybody to agree to the dozens of details we'll need to work out will be more than a little effort.



So in the PaymentRequest protocol, a SignedPaymentRequest contains a PaymentRequest that you know came from the merchant's web server (leveraging the SSL/TLS/PKI/X.509 certificate system that we all agree is the worst PKI system there is, except for all the other that have been tried):

Code:
SignedPaymentRequest
  pki_type = "x509"
  pki_data = ... certificate chain...
  signature = ...
  serialized_payment_request = ...PaymentRequest containing Outputs where payment will go...
  etc

As your paper points out, if an attacker compromises the webserver then they can redirect bitcoins to their wallet.

It would be nice if that was impossible, and your paper shows how to do that.  In the PaymentRequest scheme, one way of doing that might be:

Code:
SignedPaymentRequest
  pki_type = "x509_homomorphic"
  pki_data = ... certificate chain...
  signature = ...
  serialized_payment_request = ...PaymentRequest containing no Outputs...
  etc

The merchant's certificate in the certificate chain would have to contain their base bitcoin public key (or as you point out in the paper, generalized to a "base script"). I think that could be done using an X.509 extended attribute (anybody know if certificate authorities will sign certificates that contain non-standard extensions?).

The customer would hash the serialized_payment_request, combine it with the base key/script, and pay to that address/script.


The TODO list for implementing the simpler "x509" payment requests is fairly long (help appreciated by the way, see https://github.com/gavinandresen/paymentrequest/blob/master/TODO.txt ); implementing "x509_homomorphic" would make it even longer. I think we need to implement the simpler protocol first, because I think small merchants will want to re-use their existing web server certificates instead of paying for a new "x509_homomorphic" certificate that contains their "bitcoin identity" public key.



Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: Mike Hearn on December 13, 2012, 10:47:39 AM
The merchant's certificate in the certificate chain would have to contain their base bitcoin public key (or as you point out in the paper, generalized to a "base script"). I think that could be done using an X.509 extended attribute (anybody know if certificate authorities will sign certificates that contain non-standard extensions?).

As far as I know, they won't (would you sign data structures containing arbitrary things you didn't understand?)

But one of the things I've been thinking about for post-1.0 payment protocol specs is incrementally better PKI. We could define our own cert type (protobuf message) that can connect onto the end of an X.509 chain that supports whatever features we need. Then we could indeed put a base ECDSA key into the new cert type. It'd also allow merchants to use their SSL cert to derive certs of lower power that they can hand out to agents of the firm - certs that can only be used for signing Bitcoin payments, and which expire much faster than SSL certs would.

Simply deriving a single output using EC math is neat but has a big disadvantage - loss of privacy. The reason the payment spec allows you to specify multiple outputs (and pay with multiple transactions) is so merchants can avoid revealing personal or business financial information via the block chain. It most of the sales to them are for 50 BTC and suddenly one comes along that is 2000 BTC (perhaps you only have a single good on sale that costs that much), it leaks information to have a 2000 BTC output in the block chain. When you next use it to buy something, if the entity you're buying off knows who you are, they can infer what you sold! But if the person who bought the 2000 BTC good breaks up the payments into multiple 50 BTC outputs in multiple transactions, that information leak goes away.

Given the fact that in reality, SSL keys are held in web servers all the time, I'm not convinced the tradeoffs presented in the paper make sense. It seems better to just extend the X.509 chains with our own types of certs.


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: thanke on December 13, 2012, 05:23:58 PM
My primary thought having scan read it is that your system is a lot more complex than the one we're developing, because of the assumption that the merchants web server should not have signing keys:

Quote
For M, however, this means that signing the bill can not be done on W

I hope your primary thought is wrong and pay-to-contract (call it P2C) is just "slightly more complex despite the assumption that the merchants web server should not have signing keys".
Since nothing gets signed by the merchant at order time, in a way you can also consider it as "less complex because of the assumption that the merchants web server should not have signing keys".

But that's not a normal assumption - the web server already needs the private keys to set up SSL sessions.

The point of P2C is that no SSL connections are necessary anymore. Example: I go to my local bakery and want to order a birthday cake for tomorrow. The bakery is unexpectedly closed. There is a piece of paper pinned on the door. It says cake A costs 1BTC and cake B costs 2BTC. There is also a table printed on it with the columns "address", "A", "B". I fill out one line with (my home address, 1, 0). I scan a QR-encoded pubkey on the paper with my phone, and, since I have previously shopped with this bakery or otherwise obtained its pubkey, my phone recognizes the pubkey and shows me the name of the bakery, which it has linked to the pubkey. Then I type (home address, 1, 0) into my phone and confirm. Next morning I have one cake A at my door.

All communication between bakery and me can be tampered with by others. But what do they gain? Nothing, except denial-of-service of my order. I may not have a cake, but can show the bakery my receipt and get my money back. They even cannot fool the bakery into making cakes that nobody ordered. So maybe it wasn't so unexpected that the bakery was closed because all their customers  pay with bitcoin ;)

For the online world it means we don't need SSL connections because we don't even need interactive connections. If you are a merchant, just post your order forms somewhere and wait for incoming contracts that customers want to redeem. Check if they are paid for and then start processing the order.

The only purpose SSL keys have in our current spec is to ensure that 2nd factors can display a human-meaningful identity, to avoid substitution attacks on compromised end-user machines.

With P2C you still need your 2nd factor on the customer side and the merchant needs some kind of certificate. The point is the merchant doesn't use his certificate to sign anything at order time.
Possibly, he may want to sign the order form before posting them.

Dealing with compromised web servers is not in-scope for the current work

The intention of P2C is to make it a scope.


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: thanke on December 13, 2012, 05:43:59 PM
I like the idea of the "bill" (aka contract aka "PaymentRequest") determining the payment address, and the merchant's private bitcoin-signing key or keys being stored off their web server.

Slightly more than that, the customer can create his own PaymentRequest.

Using a Merkle tree to reveal (or not) parts of the bill is a nifty idea, but I think that is orthogonal to the payment protocol, and could be a generic way of encoding any document. I tend to agree with Mike, it feels like a complex solution to something that really isn't a problem right now (maybe if we ever have CyberCourts to adjudicate disputes between anonymous customers and merchants it will be useful).

Yes, this is orthogonal, so can be ignored for now.

PS: I was amused by:
Code:
An implementation with bitcoin would require little effort.
Writing the code should be fairly straightforward; getting everybody to agree to the dozens of details we'll need to work out will be more than a little effort.

Yes, but if we agree on a standard for a 'labelled wallet' then it's already usable. This is the only thing that strictly needs to be done inside the bitcoin client. Of course, it would be better to agree on other details as well, like the structure of the contracts. But with only labelled wallets implemented you can already do this: connect to a webshop without SSL, have the webshop display an unsigned PaymentRequest, cut and paste it into the bitcoin client as 'label', confirm merchant base key and pay.

Do you really want to base the payment protocol on hierarchical X.509 and root CAs? Personally, I feel great discomfort with that.


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: thanke on December 13, 2012, 05:58:28 PM
Then we could indeed put a base ECDSA key into the new cert type.

Not only a base ECDSA key but a base script template for direct payments to multisig outputs.

If we were only interested in ECDSA base keys, couldn't we simply add secp256k1 in addition to P-256 in OpenPGP and distribute base keys via web-of-trust? Should be trivial to change some curve parameters. [EDIT] Seems that ECDSA in openPGP is for the future, just an RFC yet. [/EDIT]

Simply deriving a single output using EC math is neat but has a big disadvantage - loss of privacy. The reason the payment spec allows you to specify multiple outputs (and pay with multiple transactions) is so merchants can avoid revealing personal or business financial information via the block chain. It most of the sales to them are for 50 BTC and suddenly one comes along that is 2000 BTC (perhaps you only have a single good on sale that costs that much), it leaks information to have a 2000 BTC output in the block chain. When you next use it to buy something, if the entity you're buying off knows who you are, they can infer what you sold! But if the person who bought the 2000 BTC good breaks up the payments into multiple 50 BTC outputs in multiple transactions, that information leak goes away.

How does having multiple outputs conflict with EC math? Just iterate some number inside the contract. Remember contracts should always be salted for privacy.


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: Mike Hearn on December 13, 2012, 07:15:42 PM
I'm confused. Are you arguing against the usage of X.509 certs or not?

If yes, where does your software get the provable identity from? In your bakery example you gloss over that, you simply assume users have shopped there before and assigned a custom label to the shops key. If the user has a compromised computer and shops at a new merchant, your scheme doesn't help unless the order form/payment request has some kind of standalone verifiable identity attached to it, that's meaningful for the first time user .... like an SSL cert.

If a company owns an SSL cert, then why would they not use it to secure their website too? Do we really want to discourage encrypted web connections?

Being able to create and sign payment requests entirely offline is potentially useful in the face of a hacked web server, if you don't have any other accepted form of identity on that server which could be used to sign payment requests. Unfortunately as two SSL certs are equivalent, that means only the case of non-secured websites. There are plenty of reasons a site might want to use SSL beyond Bitcoin.

I'm not saying the ideas in the paper are bad. Just pointing out that, for now, for most merchants/websites, it wouldn't make a practical difference because they don't have a separate identity that can be used only for Bitcoin payments and not web connections. If we can find a way to do that (by chaining two certs off the issued cert??) it'd have a lot more immediate impact.

Despite that, a future extension that lets a payment request contain base keys (in the requested scripts) that are modified by the client is still a good idea. It's something that can be added in a backwards compatible manner. As Gavin says, you'd just add some new flags to the payment request message stating that the part of the output scripts where keys should go, should have a key generated by the customer.

Re: scope. With respect, writing a paper is not the same as implementing it in all major clients. Bear in mind some of the most widely used wallets don't support hierarchical deterministic wallets at all yet, so writing specs that assume them will just delay implementation significantly.

Quote
Do you really want to base the payment protocol on hierarchical X.509 and root CAs? Personally, I feel great discomfort with that.

Nobody likes it, but there's no widely accepted equivalent. People throw around "web of trust" as if that approach hasn't been an even greater failure than PKI.

Show me another mechanism to get a certificate asserting my identity in a way that's intuitive to all end users. I don't know of one. PKI means if somebody hears about my website from a friend saying "hey, check out mikes-widget-shop.com" and they browse to it, they'll see "mikes-widget-shop.com" on their second factor device, transaction history, etc. That's meaningful - it matches the identity their friend gave them. If they see "Mikes Widget Shop, Ltd" and my rights to owning that string was verified by someone trustworthy (trademarks, etc) that's even better! EV certs are expensive and hard to obtain, but clearly not out of reach for the Bitcoin community, blockchain.info has one for instance.

Anyway, SSL PKI is a foundation on which we can build, not the end game.


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: etotheipi on December 14, 2012, 04:03:35 AM
EDIT: removed this post because it really belonged in its own thread:  https://bitcointalk.org/index.php?topic=130749.0


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: thanke on December 14, 2012, 10:13:58 AM
I'm confused. Are you arguing against the usage of X.509 certs or not?

So far, neither. As you said, the paper as well as the bakery example do not discuss how you get the provable identity from. I come back to that at the end. Some comments first.

If a company owns an SSL cert, then why would they not use it to secure their website too?

I suppose you mean an X.509 cert with all the bitcoin specific extensions that are currently being discussed, not a standard SSL cert? I ask this because I think of a "bitcoin cert" as something more universal than an "SSL cert". Yes, a bitcoin cert could be used by a company also to secure their website, and also to secure their vending/teller/etc machines which operate non-SSL. I do not want to discourage SSL connections when they are possible. My only point is to not sign payment addresses at order time with the SSL cert. The bitcoin cert can sign a weaker SSL cert, which then secures the connection. And the PaymentRequest can be partially signed, even at order time, with some weaker certs (to certify something like "yes, we have this item in stock"). Just the payment address should not be signed (consequently, can be removed alltogether from the PaymentRequest, because the customer derives the payment address).

BTW, deriving the payment address from the raw PaymentRequest (raw=not containing a payment address yet) can interoperate with the previous protocol where the merchant generates the payment address. So yes, as you say, this can be backwards compatible and customer generated payment addresses would just be an extension.  

Just pointing out that, for now, for most merchants/websites, it wouldn't make a practical difference because they don't have a separate identity that can be used only for Bitcoin payments and not web connections.

;) Most merchants are not accepting bitcoin. Aren't we early enough in the adoption to bootstrap an infrastructure for authenticated "bitcoin identities"? Better now than later.

Bear in mind some of the most widely used wallets don't support hierarchical deterministic wallets at all yet, so writing specs that assume them will just delay implementation significantly.

We don't need hierarchical deterministic wallets. The type 2 deterministic wallets that are already implemented suffice. Just agree how to encode strings to 256bit numbers, thats all.

People throw around "web of trust" as if that approach hasn't been an even greater failure than PKI.

What exactly is "web of trust". Are the PGP distribution keys in my packet manager "web of trust"?

Show me another mechanism to get a certificate asserting my identity in a way that's intuitive to all end users.

For an all-bitcoin integrated solution we can distribute the links of a string to a pubkey via the blockchain. Strings can be colored coins and the address who currently owns that colored coin defines the pubkey linked to that string. The original owner of ""Mikes Widget Shop, Ltd" is the pubkey
G["Mikes Widget Shop, Ltd"] := Hash256("Mikes Widget Shop, Ltd")*G
where G is some arbitrary base point that we all agree on and whose privkey is public. Since the address of G["Mikes Widget Shop, Ltd"] doesn't appear on the blockchain there is no owner. If you make a transaction from  G["Mikes Widget Shop, Ltd"] to your own address then you have transferred that string/colored coin to your possession. If you want to update your key or sell your string, pass on the colored coin.


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: Mike Hearn on December 14, 2012, 11:13:23 AM
I suppose you mean an X.509 cert with all the bitcoin specific extensions that are currently being discussed, not a standard SSL cert?

No, I meant an SSL cert. We haven't specced out what a "bitcoin cert" would mean or be (so far the payment protocol is largely a collaboration between Gavin and myself with some input from the others).

We don't have a way to make weaker certs right now. Perhaps there's some way we can manipulate the PKIX protocols/algorithms to get what we want, but at least with the code we've written, payment requests are signed using plain old SSL certs.

;) Most merchants are not accepting bitcoin. Aren't we early enough in the adoption to bootstrap an infrastructure for authenticated "bitcoin identities"? Better now than later.

We made the decision pretty early on not to tackle this, at least not at the moment. Building a better PKI is a lot of work and Bitcoin is always manpower constrained. Just implementing the simple SSL cert based payment protocol is a lot of work. So we want to try and think ahead, make sure we don't close any doors, but get something out the door and deployed as fast as possible. Perfect is enemy of the good and all that.

Gavin is putting effort into this because one of his top priorities is 2-factor coins. It doesn't make much sense to have a 2-factor coin if the second factor can't verify the identity of the recipient of what it's asked to sign, hence, we need a payment protocol first. So right now it's just a means to an end.

Quote
For an all-bitcoin integrated solution we can distribute the links of a string to a pubkey via the blockchain.

It's a neat idea but I don't see how to efficiently implement that in SPV clients. Also the devil is in the details. If an "identity" is any arbitrary unverified string then it's possible to play all sorts of games. For instance, if I hack a merchant using "Mike's Widget Shop" then I could sign payment requests under all sorts of identities that 99% of users would blindly accept:

"Mike's Widget Shop, Inc"
"Mike's Widget Shop    "
"Mikes Widget Shop"
"Mike's Widgets Shop"
"mikes-widget-shop.com"
"Mike's widget shop"
"Mike's widget shop<unicode control characters>"

etc. There are just tons of different ways I can claim identities confusingly similar to existing ones. All these possible attacks need to be thought through and countermeasures devised. It's just a ton of work.

DV certs at least require proof of control over a domain name which probably matches the one the user typed in, and EV certs require you actually prove control over a legally registered entity, so it's harder to get one that asserts you are called "Amaz0n Inc". How much harder, I think is an open question, but the bar is definitely higher than "just register a string".

For these and other reasons we already made the decision to go with SSL certs for v1 despite their many problems. Later on, we can build either extensions to the SSL PKI or entirely new parallel ones.


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: Gavin Andresen on December 14, 2012, 02:37:04 PM
For these and other reasons we already made the decision to go with SSL certs for v1 despite their many problems. Later on, we can build either extensions to the SSL PKI or entirely new parallel ones.

What Mike said.

Building a new PKI infrastructure is most definitely out of scope right now.

But if somebody wants to spearhead an effort to get CAs to allow extra public keys in the certificates that they issue... that might be worthwhile.

Then again, maybe not-- DNSSEC/DANE might make the CAs obsolete.


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: thanke on December 14, 2012, 05:23:02 PM
Thanks for sharing the insight how the decisions made so far about the payment protocol came about.

Quote
For an all-bitcoin integrated solution we can distribute the links of a string to a pubkey via the blockchain.

If an "identity" is any arbitrary unverified string then it's possible to play all sorts of games. For instance, if I hack a merchant using "Mike's Widget Shop" then I could sign payment requests under all sorts of identities that 99% of users would blindly accept:

"Mike's Widget Shop, Inc"
"Mike's Widget Shop    "
"Mikes Widget Shop"
"Mike's Widgets Shop"
"mikes-widget-shop.com"
"Mike's widget shop"
"Mike's widget shop<unicode control characters>"

etc. There are just tons of different ways I can claim identities confusingly similar to existing ones.

No, I didn't mean that you, as a user aka customer, receive a payment request for an alias first and then start looking up that alias' pubkey. The other way around, that's why I meant that the bitcoin cert (what ever it is, payment cert) is higher level than the SSL cert. Instead of this:
Code:
Root CA -> Intermediate CA -> foo.com certificate (X) -> child foo.com certificate (Y)
Root CA -> Intermediate CA -> foo.com certificate (X) -> bitcoin-specific certificate (Z)
We have this:
Code:
Root CA -> .. -> foo payment certificate (X) 
Root CA -> .. -> foo payment certificate (X) -> foo.com SSL certificate
Root CA -> .. -> foo payment certificate (X) -> foo.eu SSL certificate
Root CA -> .. -> foo payment certificate (X) -> foo other stuff (e.g. DNS info)
...
You first lookup the alias, e.g. 'amazon'. This results in a blockchain lookup, and a lookup to somewhere else for the derived certs, and then opens the bitcoin client and browser.
 
Typos like 'amazonn' result in the same problems as they do now.

It's a neat idea but I don't see how to efficiently implement that in SPV clients.

Have CAs that replicate the data. Merchants register an alias 'amazon' first in the blockchain, then with the CA. The CA takes the pubkey from the blockchain and produces a cert, i.e. signs the pair (alias, pubkey) with its own key. The CA key can itself be an alias in the blockchain. But SPV clients can just accept the cert. Both ways of verification can co-exist. For very important things the user may want to choose to lookup the blockchain himself.

This eliminates root CAs. Advantage: CAs become cheap and free. Free in the sense of issuing whatever kind of extended cert they want.

I agree with the issue etothepi raised in the other thread: we cannot completely rely on CAs with bitcoin. The damage of a compromised CA is too big. It's unlike e-commerce based on the traditional banking system.


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: justusranvier on December 14, 2012, 05:52:10 PM
Merchants register an alias 'amazon' first in the blockchain
Is that what namecoin does?


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: thanke on December 16, 2012, 08:56:08 AM
Then again, maybe not-- DNSSEC/DANE might make the CAs obsolete.

What if you want to transact without DNS lookups? Certs work offline, too.


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: thanke on December 16, 2012, 09:02:04 AM
Merchants register an alias 'amazon' first in the blockchain
Is that what namecoin does?

In principle, yes. Differences to namecoin would be:
* no alt-chain
* no limit to number of alias registrations per block
* alias registration is not recognizable as such, looks like arbitary transaction
* you can lookup the pubkey of a given alias (or see thats it's not yet registered), but it would be impossible to obtain a list of all registered aliases


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: Mike Hearn on December 16, 2012, 12:14:46 PM
DNSSEC signatures are conceptually no different to SSL signatures - they form a hierarchy to a root of trust. In DNSSEC there's only one root of trust, the root domain servers, whereas in SSL there are many. So you can take the DNSSEC keys/signatures and embed them in other contexts:

  http://www.imperialviolet.org/2011/06/16/dnssecchrome.html

Actually that support was taken out of Chrome due to lack of use. But the principle is the same. You could still have payments that can be verified standalone.

The main issue is that DNSSEC signatures expire fairly quickly. But I suppose wallet software could choose to be lax about expiry in some cases, if necessary.


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: abacabadabacaba on December 16, 2012, 08:25:10 PM
A payment protocol is already being developed, with input from several on the bitcoin-development SourceForge mailing list.

See https://github.com/gavinandresen/paymentrequest for software or the mailing list discussion archives http://comments.gmane.org/gmane.comp.bitcoin.devel/1574

The protocol proposed there (https://gist.github.com/4120476) has several shortcomings. Firstly, it assumes that merchant's web server would not be compromised. Mike Hearn said that the server needs to have access to SSL private key, so if it is compromised, the game is over. However, this is not true: SSL termination (http://en.wikipedia.org/wiki/SSL_termination_proxy) can be performed on a machine different from the one running the web server. Even if it is done on the same machine, web applications are typically run with limited permissions, so they can't access SSL private key.

However, in the proposed payment protocol, an application running on the server needs access to private key to be able to sign PaymentRequests. If this application is compromised, so is the key.

Secondly, this protocol can't be used securely with offline wallet because Payment structure is not signed so it can be modified by compromised customer's online computer. Modifications to refund_to attribute seem the most dangerous. Also, a merchant can reject the payment but still broadcast the transactions (possibly after some delay).

As far as I understand, thanke's proposal has none of these shortcomings.

Also, it doesn't depend on traditional PKI. Merchants may sign their master keys with SSL certificates, GPG certificates, or even both. So a normal customer can verify merchant's key using SSL certificate, but a paranoid customer, who doesn't trust governments and CAs but trusts GPG WOT, can verify the merchant's key using GPG.


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: Mike Hearn on December 17, 2012, 09:30:08 AM
SSL termination (http://en.wikipedia.org/wiki/SSL_termination_proxy) can be performed on a machine different from the one running the web server. Even if it is done on the same machine, web applications are typically run with limited permissions, so they can't access SSL private key.

This is obvious. If you have separate machines you can of course run payment request signing on them as well, and have that machine do some basic sanity checks to avoid signing obviously bogus requests (ie, to addresses that are not owned by the merchant). Same thing for compartmentalizing using separate user accounts, SELinux, trusted computing, etc.

The "compromised web server" scenario applies for small merchants where everything is done on one machine for cost reasons, which today describes most Bitcoin accepting merchants.

Quote
Secondly, this protocol can't be used securely with offline wallet because Payment structure is not signed so it can be modified by compromised customer's online computer.

The transactions themselves can't be modified. I suppose one of the tx keys could be used to sign the refund_to attribute as well, but I doubt any virus would make a profit by maliciously modifying the refund address. Refunds shouldn't be that common. It's a simple extension to sign the rest of Payment with a key used in the transactions though. Gavin can make the call.

Quote
Also, it doesn't depend on traditional PKI. Merchants may sign their master keys with SSL certificates, GPG certificates, or even both. So a normal customer can verify merchant's key using SSL certificate, but a paranoid customer, who doesn't trust governments and CAs but trusts GPG WOT, can verify the merchant's key using GPG.

As certs just encode public keys anyway, nothing stops you from directly importing certificates into a local trust store and deciding you trust them because of a WoT instead of a chain to a root CA. In practice basically no-one uses the web of trust. So this mode of operation isn't a big deal, but it can be done if you want it.


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: thanke on December 17, 2012, 10:12:52 AM
But one of the things I've been thinking about for post-1.0 payment protocol specs is incrementally better PKI. We could define our own cert type (protobuf message) that can connect onto the end of an X.509 chain that supports whatever features we need. Then we could indeed put a base ECDSA key into the new cert type. It'd also allow merchants to use their SSL cert to derive certs of lower power that they can hand out to agents of the firm - certs that can only be used for signing Bitcoin payments, and which expire much faster than SSL certs would.

Suppose we define our own (bitcoin-specific) cert type and want to chain it to an existing SSL cert. The SSL cert does not have the CA-flag enabled in the extensions, that would allow it to operate as a CA, i.e. to sign other certs. Do you suggest to simply ignore this flag (at least in v1.0) and have the bitcoin client accept the X.509 chain even though one link does not conform to the X.509 specification? If you did not suggest this, would it very bad if we did ignore this flag (again, in v1.0 only)?


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: Mike Hearn on December 17, 2012, 10:30:00 AM
Yeah, that's exactly what I was proposing.


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: Mike Hearn on December 19, 2012, 01:00:28 PM
I just wanted to point out something that maybe isn't obvious based on the previous discussions. Currently, signing payments offline with SSL keys isn't that useful because most merchants (at least today) don't have their keys in hard-to-compromise places like SSL terminators, they're running off cheap VPS systems and so on. And even if they didn't, control of the web server is often enough to get new SSL keys issued anyway.

But with DNSSEC, that is no longer the case, because the credentials you need to modify DNS are typically kept offline (in admins heads or some other safe place). There's no reason for them to be online. Even if your entire online serving setup is compromised, DNS can stay secure. So if DNSSEC/DANE was implemented as a secondary form of PKI in a future version this use case would make a lot more sense because the payment request signing key could be placed in DNS.

You don't have to lose the self-contained nature of the current payment request protocol. Although it's designed for securing online DNS lookups, DNSSEC is just another PKI - it's conceptually the same as SSL except with the DNS roots taking the place of todays certificate authorities, free signing (as far as I know) and of course it's easier to embed arbitrary data that gets signed as well. But you can still extract all the signatures and keys needed and have them be embedded into the payment request, then checked without any need to reference DNS. It conceptually forms a chain as well.

If somebody asked me to implement a payment protocol that was safe against compromised merchant servers, I'd probably do it by implementing thankes proposal (or the similar one posted in a different thread) and in parallel implementing DNSSEC as an alternative PKI. Then anyone who wants it can generate a new EC key, put the public part into a new DNS record on their domain, and then sign a bunch of payment requests offline. It would be a nice enhancement. It's also complex enough that it'd need to be part of a version 2 effort.


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: thanke on December 20, 2012, 07:20:59 PM
But with DNSSEC, that is no longer the case, because the credentials you need to modify DNS are typically kept offline (in admins heads or some other safe place). There's no reason for them to be online.

I suppose you are saying "to modify SSL" you only need control over the site because of the way EV works. But "to modify DNS" you would need  offline credentials. So far, I can follow. 

Even if your entire online serving setup is compromised, DNS can stay secure. So if DNSSEC/DANE was implemented as a secondary form of PKI in a future version this use case would make a lot more sense because the payment request signing key could be placed in DNS.

Not sure if I get the point here. The payment request signing key can not be replaced because it is in DNSSEC but it's private part would still be compromised, right? I guess the term "payment request signing key" confused me and you mean the private part to be offline, too.

For the design of the payment protocol, I would certainly like to see the PKI as easily exchangeable as possible. And even allow several PKIs in parallel. The bitcoin client should then display to the user for which PKIs authentication was successful, and for which not. 



Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: Gavin Andresen on December 20, 2012, 09:55:32 PM
And even allow several PKIs in parallel. The bitcoin client should then display to the user for which PKIs authentication was successful, and for which not.

On one hand:  "Complexity is the enemy of security."  Several PKIs in parallel is more complex.

On the other hand: "Security In Depth."  Several PKIs in parallel could be more secure. But I'd insist that ALL PKI authentications MUST be successful, otherwise you're just giving an attacker the ability to attack the least secure PKI. It would be a mistake to show users a dialog box:

Quote
DNSSEC authentication failed, but X.509 certificate authentication succeeded.
Proceed?
(Yes) (No) (Just shoot me now, please)

BUT: I think it is unlikely people will be willing deploy and keep secure multiple PKI systems, and I think the incremental security is small, so I think the right decision here is Keep It Simple, Stupid.

For example, I re-ordered the fields of SignedPaymentRequest so the entire structure doesn't have to be in memory at once to be processed, which is a suggestion from somebody considering implementing the payment protocol on a very memory-constrained hardware device. There are real tradeoffs if we make this more complex.



Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: Mike Hearn on December 20, 2012, 11:08:38 PM
Not sure if I get the point here. The payment request signing key can not be replaced because it is in DNSSEC but it's private part would still be compromised, right? I guess the term "payment request signing key" confused me and you mean the private part to be offline, too.

If you are signing requests entirely offline - like in your proposal - then compromising the web server doesn't compromise any private keys.


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: Steve on December 21, 2012, 04:43:59 AM
Maybe it would be good to take a step back when thinking about the problem.  First and foremost what I think you need is a way to deliver a secure message from one node to another, no matter what communication mechanism is employed (and by "secure" I mean signed and encrypted).  Since bitcoin is already using ECC, I see no reason not to use an ECC key pair for this as well.

So, now you have a node, and you generate an ECC key pair for communications.  There are many ways that you could exchange public keys:
- you could email a public key, along with a short hash and verify the short hash with a telephone call
- you could make a public key available on a web server over https with using an SSL certificate and CAs for authentication
- you could sign and send the public key using a PGP identity and PGP key servers
- you could use DNSSEC and whatever that entails (I have no idea, never really studied DNSSEC)

The point is, encrypt and sign the messages from endpoint to endpoint and leave the key exchange and verification protocol outside the scope for now.  With all of the different communications options available (some secure, some not), it seems unfathomable that any payment protocol would not encrypt and sign messages from endpoint to endpoint.


Title: Re: [PROPOSAL] Secure Payment Protocol
Post by: molecular on December 23, 2012, 07:29:40 AM
The point of P2C is that no SSL connections are necessary anymore. Example: I go to my local bakery and want to order a birthday cake for tomorrow. The bakery is unexpectedly closed. There is a piece of paper pinned on the door. It says cake A costs 1BTC and cake B costs 2BTC. There is also a table printed on it with the columns "address", "A", "B". I fill out one line with (my home address, 1, 0). I scan a QR-encoded pubkey on the paper with my phone, and, since I have previously shopped with this bakery or otherwise obtained its pubkey, my phone recognizes the pubkey and shows me the name of the bakery, which it has linked to the pubkey. Then I type (home address, 1, 0) into my phone and confirm. Next morning I have one cake A at my door.

All communication between bakery and me can be tampered with by others. But what do they gain? Nothing, except denial-of-service of my order. I may not have a cake, but can show the bakery my receipt and get my money back. They even cannot fool the bakery into making cakes that nobody ordered. So maybe it wasn't so unexpected that the bakery was closed because all their customers  pay with bitcoin ;)

Mr. Hanke, let me thank you for explaining things so even I can understand them ;).

It's very reassuring to see bitcoin is being recognized and worked on by parts of the german research community, btw. Danke!