2015-12-04 02:24:29 +01:00
<pre>
BIP: XXX
Title: Out of Band Address Exchange using Encrypted PaymentRequests
2016-02-16 19:52:47 +01:00
Authors: Justin Newton <justin@netki.com>
2016-02-10 18:43:21 +01:00
Matt David <mgd@mgddev.com>
2015-12-07 18:42:25 +01:00
Aaron Voisine <voisine@gmail.com>
2016-01-07 22:53:51 +01:00
James MacWhyte <macwhyte@gmail.com>
2015-12-04 02:24:29 +01:00
Status: Draft
Type: Informational
Created: 2015-11-20
</pre>
==Abstract==
2016-01-11 20:05:26 +01:00
This BIP is an extension to BIP 70 that provides two enhancements to the existing Payment Protocol.
2015-12-04 02:24:29 +01:00
2016-02-18 01:11:59 +01:00
# It allows the requestor (Sender) of a Payment Request to voluntarily sign the original request and provide a certificate to allow the payee to know the identity of who they are transacting with.
2016-01-11 20:05:26 +01:00
# It encrypts the Payment Request that is returned, before handing it off to the SSL/TLS layer to prevent man in the middle viewing of the Payment Request details.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
2015-12-04 02:24:29 +01:00
"OPTIONAL" in this document are to be interpreted as described in RFC 2119.
2016-02-18 01:11:59 +01:00
==Definitions==
{| class="wikitable"
| Sender || Entity wishing to transfer value that they control
|-
| Receiver || Entity receiving a value transfer
|}
2015-12-04 02:24:29 +01:00
==Motivation==
2016-01-11 20:05:26 +01:00
The motivation for defining this extension to the BIP70 Payment Protocol is to allow 2 parties to exchange payment information in a permissioned and encrypted way such that wallet address communication can become a more automated process. Additionally, this extension allows for the requestor of a PaymentRequest to supply a certificate and signature in order to facilitate identification for address release. This also allows for automated creation of off blockchain transaction logs that are human readable, containing who you transacted with, in addition to the information that it contains today.
2016-02-16 22:19:16 +01:00
The motivation for this extension to BIP70 is threefold:
2016-01-11 20:05:26 +01:00
2016-02-18 01:11:59 +01:00
# Ensure that the payment details can only be seen by the participants in the transaction, and not by any third party.
2016-02-16 22:19:16 +01:00
# Enhance the Paument Protocol to allow for store and forward servers in order to allow, for example, mobile wallets to sign and serve Payment Requests.
2016-01-11 20:05:26 +01:00
# Allow a sender of funds the option of sharing their identity with the receiver. This information could then be used to:
2016-01-11 20:06:47 +01:00
2016-02-16 19:56:08 +01:00
#* Make bitcoin logs more human readable
#* Give the user the ability to decide who to release payment details to
#* Allow an entity such as a political campaign to ensure donors match regulatory and legal requirements
#* Allow for an open standards based way to meet regulatory requirements
#* Automate the active exchange of payment addresses, so static addresses and BIP32 X-Pubs can be avoided to maintain privacy and convenience
2016-01-11 20:05:26 +01:00
In short we wanted to make bitcoin more human, while at the same time improving transaction privacy.
2015-12-04 02:24:29 +01:00
2016-02-10 18:43:21 +01:00
==Example Use Cases==
2016-02-02 04:36:45 +01:00
2016-02-16 19:56:08 +01:00
1. Address Book
2016-02-02 04:36:45 +01:00
2016-02-10 18:43:21 +01:00
Let's say a Bitcoin wallet developer would like to offer the ability to store an "address book" of payees, so users could
send multiple payments to known entities without having to request an address every time. Static addresses compromise
privacy, and address reuse is considered a security risk. BIP32 X-Pubs allow the generation of unique addresses, but
watching an X-Pub chain for each person you wish to receive funds from is too resource-intensive for mobile applications,
2016-02-18 01:11:59 +01:00
and there is always a risk of unknowingly sending funds to an X-Pub address after the owner has lost access to the
2016-02-10 18:43:21 +01:00
corresponding private key.
With this BIP, Bitcoin wallets could maintain an "address book" that only needs to store each payee's public key. Adding
an entry to one's address book could be done by using a Wallet Name, scanning a QR code, sending a URI through a text message or e-mail, or
searching a public repository. When the user wishes to make a payment, their wallet would do all the work in the background
to communicate with the payee's wallet to receive a unique payment address. If the payee's wallet has been lost, replaced,
or destroyed, no communication will be possible, and the sending of funds to a "dead" address is prevented.
2016-02-16 19:56:08 +01:00
2. Individual Permissioned Address Release
2016-02-10 18:43:21 +01:00
Let's say a Bitcoin wallet developer would like to offer the ability for a user to individually release address information
2016-02-18 01:11:59 +01:00
to a new potential sending party only if they can confirm the identity of the potential sending party. Currently, BIP70 specifies that
2016-02-10 18:43:21 +01:00
the Merchant Server respond to a "pay now" style request with a PaymentRequest, releasing address and X.509 certificate identity
information of the potential receiving party.
With this BIP, Bitcoin wallets could prompt a wallet user to release payment information while displaying identity
information about the potential sending party via an included certificate. This allows the potential receiving party to
make a more informed decision regarding to whom they are releasing payment and identity information.
2016-02-16 19:56:08 +01:00
3. Using Store & Forward Servers
2016-02-10 18:43:21 +01:00
Let's say a Bitcoin wallet developer would like to use a public Store & Forward service for an asynchronous address
exchange. This is a common case for mobile and offline wallets.
With this BIP, returned payment information is encrypted with an ECDH-computed shared key before sending to a Store & Forward
service. In this case, a successful attack against a Store & Forward service would not be able to read or modify wallet address
or payment information, only delete encrypted messages.
2016-02-16 22:41:56 +01:00
[MATT PLEASE INCLUDE TEXT HERE REGARDING OTHER STORE AND FORWARD MODIFICATIONS]
2016-02-02 04:36:45 +01:00
2015-12-04 22:26:50 +01:00
==New Messages==
2015-12-04 02:24:29 +01:00
2016-02-16 02:19:37 +01:00
===EncryptedInvoiceRequest===
The EncryptedInvoiceRequest message allows a Sender to send an encrypted InvoiceRequest to the Receiver such that the details of the InvoiceRequest are kept secret.
<pre>
message EncryptedInvoiceRequest {
required bytes encrypted_invoice_request = 1; // Encrypted Serialized InvoiceRequest
required bytes sender_public_key = 2; // Sender's EC Public Key
required bytes invoice_request_hash = 3; // SHA256 of Serialized InvoiceRequest
}
</pre>
2015-12-04 02:30:04 +01:00
{| class="wikitable"
2016-02-16 02:19:37 +01:00
! Field Name</b> !! Description
2015-12-04 02:31:09 +01:00
|-
2016-02-16 02:19:37 +01:00
| encrypted_invoice_request || AES-256-CBC Encrypted Serialized InvoiceRequest
|-
| sender_public_key || Sender's EC Public Key
|-
| invoice_request_hash || SHA256 Hash of Non-Encrypted, Serialized InvoiceRequest
2015-12-04 02:24:29 +01:00
|}
2015-12-04 22:26:50 +01:00
===InvoiceRequest===
2016-02-16 02:19:37 +01:00
The InvoiceRequest message allows a Sender to send information to the Receiver such that they can create and return a EncryptedPaymentRequest.
2015-12-04 02:24:29 +01:00
<pre>
message InvoiceRequest {
required bytes sender_public_key = 1; // Sender's EC Public Key
2016-01-07 20:37:09 +01:00
required uint64 nonce = 2; // Microseconds since epoch
optional uint64 amount = 3 [default = 0]; // amount is integer-number-of-satoshis
optional string pki_type = 4 [default = "none"]; // none / x509+sha256
optional bytes pki_data = 5; // Depends on pki_type
2016-02-16 02:19:37 +01:00
optional string notification_url = 6; // URL to notify on EncryptedPaymentRequest ready
2016-01-07 20:37:09 +01:00
optional bytes signature = 7; // PKI-dependent signature
2015-12-04 02:24:29 +01:00
}
</pre>
2015-12-04 02:30:04 +01:00
{| class="wikitable"
! Field Name !! Description
2015-12-04 02:32:01 +01:00
|-
2015-12-04 02:24:29 +01:00
| sender_public_key || Sender's EC Public Key
2015-12-04 02:31:09 +01:00
|-
2016-01-07 20:37:09 +01:00
| nonce || Microseconds since epoch
|-
2015-12-04 02:24:29 +01:00
| amount || amount is integer-number-of-satoshis (default: 0)
2015-12-04 02:31:09 +01:00
|-
2015-12-04 02:24:29 +01:00
| pki_type || none / x509+sha256 (default: "none")
2015-12-04 02:31:09 +01:00
|-
2015-12-04 02:24:29 +01:00
| pki_data || Depends on pki_type
2015-12-04 02:31:09 +01:00
|-
2016-02-16 02:35:23 +01:00
| notification_url || Secure (usually HTTPS) location where an EncryptedPaymentRequest (see below) SHOULD be sent when ready
2015-12-04 02:31:09 +01:00
|-
2015-12-04 02:24:29 +01:00
| signature || PKI-dependent signature
|}
2016-02-16 02:19:37 +01:00
===EncryptedPaymentRequest===
2015-12-04 02:24:29 +01:00
2016-02-16 02:19:37 +01:00
The EncryptedPaymentRequest message is an encapsulating message that allows the transmission of an encrypted, serialized PaymentRequest.
2015-12-04 02:24:29 +01:00
<pre>
2016-02-16 02:19:37 +01:00
message EncryptedPaymentRequest {
required bytes encrypted_payment_request = 1; // Encrypted Serialized PaymentRequest
2015-12-05 00:16:32 +01:00
required bytes receiver_public_key = 2; // Receiver's EC Public Key
2016-01-07 20:37:09 +01:00
required bytes payment_request_hash = 3; // SHA256 of Serialized PaymentRequest
2015-12-05 00:16:32 +01:00
}
2015-12-04 02:24:29 +01:00
</pre>
2015-12-04 02:30:04 +01:00
{| class="wikitable"
! Field Name</b> !! Description
2015-12-04 02:31:09 +01:00
|-
2015-12-04 20:10:01 +01:00
| encrypted_payment_request || AES-256-CBC Encrypted Serialized PaymentRequest
2015-12-04 02:31:09 +01:00
|-
2015-12-04 20:10:01 +01:00
| receiver_public_key || Receiver's EC Public Key
2015-12-04 02:31:09 +01:00
|-
2015-12-04 20:10:01 +01:00
| payment_request_hash || SHA256 Hash of Non-Encrypted, Serialized PaymentRequest
2015-12-04 02:24:29 +01:00
|}
2016-02-17 00:22:18 +01:00
==InvoiceRequest / PaymentRequest Process==
The process overview for using InvoiceRequests and receiving encrypted PaymentRequests is defined below in two sections.
Optionally, the Sender MAY choose to encrypt the InvoiceRequest message and therefore MUST follow the <b>Encrypted InvoiceRequest Overview</b> process.
2015-12-04 02:24:29 +01:00
2016-02-17 00:22:18 +01:00
===Non-Encrypted InvoiceRequest Overview===
2015-12-04 20:33:06 +01:00
# Sender creates InvoiceRequest
2015-12-04 20:10:01 +01:00
# Sender transmits InvoiceRequest to Receiver
2015-12-04 20:33:06 +01:00
# Receiver validates InvoiceRequest
2015-12-04 20:10:01 +01:00
# Receiver creates PaymentRequest
2015-12-04 20:33:06 +01:00
# Receiver encrypts the PaymentRequest
2016-02-17 00:22:18 +01:00
# Receiver creates EncryptedPaymentRequest (containing an encrypted PaymentRequest)
# Receiver transmits EncryptedPaymentRequest to Sender
# Sender validates EncryptedPaymentRequest
# Sender decrypts and validates encrypted PaymentRequest
<img src="bip-ir/invoice-request-process.png"></img>
2015-12-04 02:24:29 +01:00
2016-02-17 00:22:18 +01:00
===Encrypted InvoiceRequest Overview===
# Sender retrieves Receiver InvoiceRequest Public Key
2015-12-04 20:33:06 +01:00
# Sender creates InvoiceRequest
2016-02-16 02:19:37 +01:00
# Sender encrypts the InvoiceRequest
# Sender creates EncryptedInvoiceRequest (containing an encrypted InvoiceRequest)
# Sender transmits EncryptedInvoiceRequest to Receiver
2016-02-17 00:22:18 +01:00
# Receiver decrypts and validates EncryptedInvoiceRequest
2015-12-04 20:33:06 +01:00
# Receiver validates InvoiceRequest
2015-12-04 20:10:01 +01:00
# Receiver creates PaymentRequest
2015-12-04 20:33:06 +01:00
# Receiver encrypts the PaymentRequest
2016-02-16 02:19:37 +01:00
# Receiver creates EncryptedPaymentRequest (containing an encrypted PaymentRequest)
# Receiver transmits EncryptedPaymentRequest to Sender
# Sender validates EncryptedPaymentRequest
2015-12-04 20:33:06 +01:00
# Sender decrypts and validates encrypted PaymentRequest
2015-12-04 20:10:01 +01:00
2016-02-17 00:22:18 +01:00
<b>NOTE:</b> See section <b>Initial Public Key Retrieval for InvoiceRequest Encryption</b> below for possible options to retrieve Receiver InvoiceRequet public keys.
2015-12-05 00:16:32 +01:00
2016-02-17 00:22:18 +01:00
<img src="bip-ir/encrypted-invoice-request-process.png"></img>
2015-12-05 00:16:32 +01:00
2016-02-17 00:22:18 +01:00
==Message Interaction Details==
2015-12-05 00:16:32 +01:00
2016-02-16 02:19:37 +01:00
===EncryptedInvoiceRequest===
2016-02-17 00:22:18 +01:00
Sender MUST transmit EncryptedInvoiceRequest to Receiver (or Receiver's agent) via TLS-protected HTTP. Sender transmitting
2016-02-16 02:19:37 +01:00
EncryptedInvoiceRequest message MUST set appropriate Content-Type headers as specified here:
<pre>Content-Type: application/bitcoin-encrypted-invoicerequest</pre>
2015-12-04 22:26:50 +01:00
2016-02-17 00:22:18 +01:00
===InvoiceRequest===
Sender MUST transmit InvoiceRequest to Receiver (or Receiver's agent) via TLS-protected HTTP. Sender transmitting
InvoiceRequest message MUST set appropriate Content-Type headers as specified here:
2015-12-04 22:26:50 +01:00
<pre>Content-Type: application/bitcoin-invoicerequest</pre>
2016-02-17 00:22:18 +01:00
===EncryptedPaymentRequest===
2016-02-16 02:19:37 +01:00
Receiver MUST transmit EncryptedPaymentRequest to Sender (or Sender's agent) via TLS-protected HTTP. Receiver transmitting
EncryptedPaymentRequest messages MUST set appropriate Content-Type headers as specified here:
<pre>Content-Type: application/bitcoin-encrypted-paymentrequest</pre>
2015-12-04 22:26:50 +01:00
2016-02-17 00:22:18 +01:00
===Message or Communication Errors===
2016-01-20 22:16:22 +01:00
An invalid or unparsable message or communications error MUST be communicated to the party that initiated the communication. This
SHOULD be done through standard HTTP Status Code messaging ([https://tools.ietf.org/html/rfc7231 RFC 7231 Section 6]).
2015-12-04 22:26:50 +01:00
2016-02-17 00:22:18 +01:00
==Process Step Details==
2015-12-04 02:24:29 +01:00
===InvoiceRequest Message Creation===
* Create an InvoiceRequest message
2016-01-07 20:37:09 +01:00
* sender_public_key MUST be set to the public key of an EC keypair
2016-01-12 00:22:06 +01:00
* nonce MUST be set to a non-repeating number. The current epoch time in microseconds SHOULD be used, unless the creating device doesn't have access to a RTC (in the case of a smart card, for example)
2016-01-20 22:16:22 +01:00
* Amount is optional. If the amount is not specified by the InvoiceRequest, the Receiver MAY specify the amount in the returned PaymentRequest. If an amount is specified by the InvoiceRequest and a PaymentRequest cannot be generated for that amount, the InvoiceRequest SHOULD be rejected with HTTP status code 406.
2016-02-16 02:19:37 +01:00
* Set notification_url to URL that the Receiver will submit completed EncryptedPaymentRequest to
2015-12-04 02:24:29 +01:00
* If NOT including certificate, set pki_type to "none"
* If including certificate:
** Set pki_type to "x509+sha256"
2015-12-04 20:40:43 +01:00
** Set pki_data as it would be set in BIP-0070 (see [https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki#Certificates Certificates]) section)
2016-01-07 20:37:09 +01:00
** Sign InvoiceRequest with signature = "" using the X509 Certificate's private key
** Set signature value to the computed signature
2015-12-04 02:24:29 +01:00
2016-02-16 02:19:37 +01:00
===EncryptedInvoiceRequest Message Creation===
* Create an EncryptedInvoiceRequest
* Retrieve endpoint public key to use in <b>ECDH Point Generation</b> as specified in <b>Initial Public Key Retrieval for InvoiceRequest Encryption</b> (see below)
* sender_public_key MUST be set to the public key of an EC keypair
* invoice_request_hash MUST be set to the SHA256 hash of the serialized InvoiceRequest (without encryption)
2016-02-16 02:35:23 +01:00
* Encrypt the serialized InvoiceRequest using AES-256-CBC setup as described in <b>ECDH Point Generation and AES-256 (CBC Mode) Setup (see below)</b>
2016-02-16 02:19:37 +01:00
* encrypted_invoice_Request MUST be set to the encrypted values of the InvoiceRequest
2015-12-04 20:10:01 +01:00
===InvoiceRequest Validation===
* Validate sender_public_key is a valid EC public key
2016-01-20 22:16:22 +01:00
* The nonce MUST not be repeated. The service receiving the InvoiceRequest MAY use whatever method to make sure that the nonce is never repeated.
2015-12-04 20:10:01 +01:00
* Validate notification_url if set, contains characters deemed valid for a URL (avoiding XSS related characters, etc).
* If pki_type is None, InvoiceRequest is VALID
* If pki_type is x509+sha256 and signature is valid for the serialized InvoiceRequest where signature is set to "", InvoiceRequest is VALID
2015-12-04 02:24:29 +01:00
2016-02-16 02:19:37 +01:00
===EncryptedPaymentRequest Message Creation and PaymentRequest Encryption===
2015-12-05 00:16:32 +01:00
* Encrypt the serialized PaymentRequest using AES-256-CBC setup as described in <b>ECDH Point Generation and AES-256 (CBC Mode) Setup (see below)</b>
2016-02-16 02:19:37 +01:00
* Create EncryptedPaymentRequest message
2015-12-04 02:24:29 +01:00
* Set encrypted_payment_request to be the encrypted value of the PaymentRequest
* Set receiver_public_key to the Receiver's EC public key (of which the private key was previously used in ECDH secret point calculation)
* Set payment_request_hash to generated SHA256 hash of the serialized PaymentRequest (without encryption)
2016-02-16 02:19:37 +01:00
===EncryptedPaymentRequest Validation and Decryption===
2015-12-05 00:16:32 +01:00
* Decrypt the serialized PaymentRequest using AES-256-CBC setup as described in <b>ECDH Point Generation and AES-256 (CBC Mode) Setup (see below)</b>
2015-12-04 02:24:29 +01:00
* Validate payment_request_hash matches SHA256 of the decrypted, serialized PaymentRequest
* Deserialize the serialized PaymentRequest
2015-12-04 20:10:01 +01:00
===ECDH Point Generation and AES-256 (CBC Mode) Setup===
* Generate the '''secret point''' using [https://en.wikipedia.org/wiki/Elliptic_curve_Diffie– Hellman ECDH] using the local entity's private key and the remote entity's public key as inputs.
* Initialize [http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf HMAC_DRBG]
** Use '''secret point's''' X value for Entropy
2016-01-07 20:37:09 +01:00
** Use the given InvoiceRequest's nonce field for Nonce
2015-12-04 20:10:01 +01:00
* Initialize AES-256 in CBC Mode
** Use HMAC_DRBG.GENERATE(32) as the Encryption Key (256 bits)
** Use HMAC_DRBG.GENERATE(16) as the Initialization Vector (IV) (128 bits)
2016-02-16 02:19:37 +01:00
===Initial Public Key Retrieval for InvoiceRequest Encryption===
Initial public key retrieval for InvoiceRequest encryption can be done in a number of ways including, but not limited to, the following:
2016-02-16 02:35:23 +01:00
* Wallet Name public key asset type resolution - DNSSEC-validated name resolution returns Base64 encoded DER-formatted EC public key via TXT Record [https://www.ietf.org/rfc/rfc5480.txt RFC 5480]
* Key Server lookup - Key Server lookup (similar to PGP's pgp.mit.edu) based on key server identifier (i.e., e-mail address) returns Base64 encoded DER-formatted EC public key [https://www.ietf.org/rfc/rfc5480.txt RFC 5480]
2016-02-16 02:19:37 +01:00
* QR Code - Use of QR-code to encode DER-formatted EC public key [https://www.ietf.org/rfc/rfc5480.txt RFC 5480]
==Payment Messages with a Store & Foward Server==
[https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki#Payment Payment] messages are used in the same way
with the following exception:
When a Store & Forward server is in use during the Payment Protocol exchange, a Payment message generated as the result of a
received EncryptedPaymentRequest MUST be accepted by a Store & Forward server if the Payment message is appropriately correlated
to an InvoiceRequest/PaymentRequest exchange. This correlation SHOULD BE done in order to decrease spam requests. The accepted
2016-02-16 02:35:23 +01:00
Payment message IS NOT validated as the Store & Forward server does not have access to the original PaymentRequest.
2016-02-16 02:19:37 +01:00
2016-01-20 22:16:22 +01:00
==Implementation==
2016-01-20 22:19:25 +01:00
A reference implementation for a Store & Forward server supporting this proposal can be found here:
[https://github.com/netkicorp/addressimo Addressimo]
A reference client implementation can be found in the InvoiceRequest functional testing for Addressimo here:
[https://github.com/netkicorp/addressimo/blob/master/functest/functest_ir.py InvoiceRequest Client Reference Implementation]
2016-01-20 22:16:22 +01:00
==BIP70 Extension==
The following flowchart is borrowed from BIP70 and expanded upon in order to visually describe how this BIP is an extension to BIP70.
<img src="bip-ir/bip70-extension.png"></img>
==Mobile to Mobile Example==
The following diagram shows a sample flow in which one mobile client is sending value to a second mobile client with the use
2016-02-16 02:19:37 +01:00
of an InvoiceRequest, a Store & Forward server, and a EncryptedPaymentRequest.
2016-01-20 22:16:22 +01:00
<img src="bip-ir/mobile-sf-bip70-extension.png"></img>
2016-02-16 02:19:37 +01:00
==References==
2015-12-04 02:24:29 +01:00
* [[bip-0070.mediawiki|BIP70 - Payment Protocol]]
* [https://en.wikipedia.org/wiki/Elliptic_curve_Diffie– Hellman ECDH]
* [http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf HMAC_DRBG]
2015-12-07 18:42:25 +01:00
* [https://tools.ietf.org/html/rfc6979 RFC6979]
2016-02-18 01:11:59 +01:00
* [https://en.bitcoin.it/wiki/Address_reuse Address Reuse]