Skip to content
This repository has been archived by the owner on Jan 19, 2024. It is now read-only.

Consignment ECDH encryption + requiring consignment signature from payee for ACK/NACK #11

Open
adambor opened this issue Dec 20, 2023 · 1 comment

Comments

@adambor
Copy link

adambor commented Dec 20, 2023

The rgb-proxy-server is currently not very private & secure:

  1. The proxy server can read the full consignment data in the clear
  2. The proxy server can lie about whether the payee actually got the consignment (it can just return ACK/NACK as a response to get_ack_info at will)

This might lead to proxy server spying on rgb transfers and some bad UX if the proxy server ACKs the request, when the payee wanted to NACK it. The proxy server can also selectively censor some RGB consignments.

To solve this issue I propose the following protocol flow (we also discussed this in Viareggio with @dr-orlovsky):

  1. Payee generates an ephemeral EC keypair (ep0)
  2. The invoice passed from payee to payer contains an ephemeral public key of the payee (ep0.pubkey)
  3. Payer generates an ephemeral EC keypair (ep1)
  4. Payer generates ECDH shared secret (ep1.privkey * ep0.pubkey) and derives encryption key (enckey) from it
  5. Payer uses encryption (enckey) to encrypt the consignment file
  6. Payer sends encrypted consignment file to the proxy server along with his ephemeral public key (ep1.pubkey)
  7. Payee calls get_consignment, which returns ephemeral public key of the payer as a header and starts sending the encrypted consignment in the response body
    • payee reconstructs the shared secret (ep1.pubkey * ep0.privkey) and derives the encryption key (enckey), this is done as soon as HTTP headers are returned
    • payee starts stream decrypting the encrypted consignment in the response body, it is important for the payee to periodically check if the received & decrypted data makes sense (e.g. it is a valid consignment file format), if that's not the case the payee should cut the connection as soon as he detects an invalid format - to prevent wasting bandwidth.
  8. Payee responds with ACK/NACK to the proxy server signed by his ephemeral keypair (ep0), the message to sign is:
    • hash("ACK" | hash(unencrypted_consignment))
    • hash("NACK" | hash(unencrypted_consignment))
  9. Payer retrieves the result (ACK/NACK) and verifies it is correctly signed by payee's ephemeral keypair (ep0) - recall the payer knows the payee's ephemeral public key (ep0.pubkey) from the invoice.

Posting this here to gather some feedback first - I would be open to implement this flow into the proxy server in a PR once it gets approval, it just needs a few more fields in the forwarded data and should be fairly easy to accomplish. The majority of the work needs to be done on the client side (generating ephemeral keypair, deriving shared secret and signing/verifying) which is (I guess) outside the scope of this repo.

@fedsten
Copy link
Collaborator

fedsten commented Jan 19, 2024

I think the proposal is very good and would add a lot of the much needed extra security and privacy to the payment flow. However it is quite a big change, so I suggest to implement it as a new separate project, and leave this one a the simpler unencrypted alternative.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants