Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIDO Payment Support #1570

Closed
cyberphone opened this issue Feb 15, 2021 · 18 comments
Closed

FIDO Payment Support #1570

cyberphone opened this issue Feb 15, 2021 · 18 comments
Milestone

Comments

@cyberphone
Copy link

cyberphone commented Feb 15, 2021

Since the SPC specification is to be discussed at https://github.com/w3c/webpayments/wiki/Agenda-FTF2021, I took the liberty outlining an enhanced scheme that may serve as "inspiration". It is not entirely complete (enrollment is currently missing), but the core is hopefully understandable. The proposal mainly deals with security constructs and data flows.

Updated: 2021-02-19

Enhancements

  • Privacy: User-unique information (PII) is neither required nor provided to external actors.
  • Security: Reduced attack space since no sensitive data is given to external actors. Encryption replaces tokenization.
  • Universality: Applicable to any account based payment system.
  • Simplicity: In similarity to EMV the scheme does not not depend on external challenge data or centralized registries holding enrolled account numbers.

Although not a part of this specification, the underpinning authorization scheme also opens the door to non-direct payments, including secure (tokenized) versions of Card-on-File.

Prerequisite - Payment Credentials

The scheme outlined here depends on that the User already has received a payment credential from the Issuer in an enrollment process. A payment credential is supposed to at least contain the following elements:

  • A User specific (unique) FIDO key for signing payment authorization data.
  • An accountId associated with the FIDO signature key.
  • An Issuer specific (shared) public key for encrypting payment authorization data.
  • An issuerId in the form of a BIN number or a URL associated with the Issuer.
  • An icon identifying the payment credential for the User.

A payment credential is associated with a specific paymentMethod established during enrollment.

Detailed Operation

The different steps in following state diagram are described in this section.
state-diagram
Note: this specification does not elaborate on the return data from the Issuer etc.

1. The Merchant creates payment request data (PREQ) and invokes the payment request API with it:

{
  "id": "7040566321",
  "payee": "Rocket Shop",
  "amount": {
    "currency": "EUR",
    "value": "435.00"
  }
}

Note: the JSON object above outlines the conceptual data before being translated into a compliant Payment Request call. It seems that payee currently have no obvious place in the API.

2. The Browser responds with PREQ rendered in a user interpretable fashion:
browser-display
Non-normative UI.

3. The User authorizes the request with a fingerprint, PIN, or similar.

4. After successful user authorization, the Browser MUST perform the following internal steps.

4.1 Calculate a Base64Url-encoded SHA256 hash of PREQ, canonicalized according to RFC8785. Expressed as a formula: BASE64URL(SHA256(RFC8785(PREQ))). Applied to the sample data, the result of this operation should be "Zf6qUOoA3NWM77rksuji2tE7tlGHrzu9K5Y_AGn5tkw".

4.2 Create an authorization data object (AD) with data needed for processing by the Issuer:

{
  "requestHash": {
    "algorithm": "S256",
    "value": "Zf6qUOoA3NWM77rksuji2tE7tlGHrzu9K5Y_AGn5tkw"
  },
  "payeeHost": "spaceshop.com",
  "accountId": "FR7630002111110020050014382",
  "timeStamp": "2021-02-18T10:32:35+01:00"
}
  • requestHash cryptographically binds PREQ to AD.
  • payeeHost is picked-up by the Browser.
  • accountId denotes the actual account number to be debited and is retrieved from the payment credential. The sample uses a French IBAN number but it could equally well be a credit card PAN.
  • timeStamp is generated internally.

4.3 Using the FIDO signature key, sign AD using JWS/CT resulting in the following completed AD object:

{
  "requestHash": {
    "algorithm": "S256",
    "value": "Zf6qUOoA3NWM77rksuji2tE7tlGHrzu9K5Y_AGn5tkw"
  },
  "payeeHost": "spaceshop.com",
  "accountId": "FR7630002111110020050014382",
  "timeStamp": "2021-02-18T10:32:35+01:00",
  "signature": "eyJhbGciOiJFUzI1NiIsImp3ayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6IjZCS3hwdHk4Y0ktZXhEekNraC1nb1U2ZFhxM01iY1kwY2QxTGFBeGlOclUiLCJ5IjoibUNiY3ZVem00NGozTHQyYjVCUHlRbG9ROTF0ZjJEMlYtZ3plVXhXYVVkZyJ9fQ..XvwOEMX4CG8l5nq-rOSkEbdFRcrhtAdQ6s1HFtLgiWMoNliiPSJnurmBnkBzudoLucBLVRwql6ZWANq1AALcXA"
}

Although not visible in the listing above (due to JWS' Base64Url-encoding requirements on JWS header data), AD signatures MUST provide a key identifier. In the sample, the following JWK holding the public key was used:

{
  "kty": "EC",
  "crv": "P-256",
  "x": "6BKxpty8cI-exDzCkh-goU6dXq3MbcY0cd1LaAxiNrU",
  "y": "mCbcvUzm44j3Lt2b5BPyQloQ91tf2D2V-gzeUxWaUdg"
}

4.4 For privacy and security reasons, the completed AD object MUST be encrypted by a public key provided by the Issuer through the payment credential. This specification builds on JWE (RFC7516) using the compact serialization mode. The selection between an RSA or ECDH encryption scheme is at the discretion of the Issuer. AD objects MUST be JSON-serialized to UTF-8 before being encrypted. The resulting JWE string would look something like this (with line breaks for display purposes only):

eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ.OKOawDo13gRp2oja
HV7LFpZcgV7T6DVZKTyKOMTYUmKoTCVJRgckCL9kiMT03JGeipsEdY3mx_etLbb
WSrFr05kLzcSr4qKAq7YN7e9jwQRb23nfa6c9d-StnImGyFDbSv04uVuxIp5Zms
1gNxKKK2Da14B8S4rzVRltdYwam_lDp5XnZAYpQdb76FdIKLaVmqgfwX7XWRxv2
322i-vDxRfqNzo_tETKzpVLzfiwQyeyPGLBIO56YJ7eObdv0je8860ppamavo35
UgoRdbYaBcoh9QcfylQr66oc6vFWXRcZ_ZT2LawVCWTIy3brGPi6UklfCpIMfIj
f7iGdXKHzg.48V1_ALb6US04U3b.5eym8TW_c8SuK0ltJ3rpYIzOeDQz7TALvtu
6UG9oMo4vpzs9tX_EFShS8iB7j6jiSdiwkIr3ajwQzaBtQD_A.XFBoMYUZodetZ
dvTiFvSkQ

To simplify documentation, the JWE string is subsequently referred to as "JWE-Encrypted-AD".

Note that due to the end-2-end encryption scheme, the domain constraints usually associated with FIDO, do not apply.

4.5 Put the encrypted AD into a payment response object (PRES) together with clear text data needed for payment "backend" processing:

{
  "encryptedAuthorization": "JWE-Encrypted-AD",
  "paymentMethod": "https://europeanpaymentsinitiative.eu/spc",
  "issuerId": "https://mybank.fr/payment"
}

paymentMethod is the actual SPC method used. See #1570 (comment).

Note that by encrypting authorization data, the "routing" of payment requests with respect to the Issuer is separated from account numbers. By using URLs like in the example, the need for databases holding BIN numbers is eliminated.

5. The Browser returns PRES to the Merchant.

6. The Merchant puts its original PREQ and the received PRES into an authorization request object (AREQ):

{
  "paymentRequest": {
    "id": "7040566321",
    "payee": "Rocket Shop",
    "amount": "435.00",
    "currency": "EUR"
  },
  "encryptedAuthorization": "JWE-Encrypted-AD",
  "paymentMethod": "https://europeanpaymentsinitiative.eu/spc",
  "issuerId": "https://mybank.fr/payment"
}

7. The Merchant sends AREQ to the Acquirer service associated with the specific paymentMethod. Note that authentication of AREQ is out of scope for this specification.

8. The Acquirer validates the authenticity and syntax of the received AREQ as well as looking up the Issuer through the supplied issuerId.

9. The Acquirer augments the received AREQ with additional data (like Merchant collection account), and forwards the completed object to the designated Issuer. Note that authentication of AREQ is out of scope for this specification.

10. The Issuer MUST now perform a number of steps to verify the correctness of the received AREQ. With respect to the User the following steps are the most significant:

10.1 Decrypt the encryptedAuthorization object in AREQ using the Issuer specific (but shared) decryption key. Set result as AD.

10.2 Retrieve the signature key declared in the JWS header of the AD signature element. Abort if unknown.

10.3 Verify that the retrieved signature key is associated with the AD accountId element. Abort on failure.

10.4 Validate the AD signature using the retrieved signature key. Abort on failure.

10.5 Perform the same calculation as specified in 4.1 on the received paymentRequest object and compare the result with the AD requestHash. Abort on failure.

10.6 Check that the AD timeStamp element is within limits. Tentative: CurrentTime - 600s < timeStamp < CurrentTime + 60s. Abort on failure.

10.7 To cope with possible replays, check that the received AD has not already been utilized. Ideally, the Issuer should support idempotent operation to facilitate benign transaction retries.

Available funds also needs to be validated but that is out of scope for this specification.
@equalsJeffH @nadalin @rlin1

@adrianhopebailie
Copy link

How does the browser determine which payment credential to use in step 2?
My assumption is that the user has multiple and they are only usable on specific payment networks for specific payment method.s

@cyberphone
Copy link
Author

Right, this proposal does not describe the selection mechanism because the assumption is that the existing PaymentRequest selection scheme will be sufficient.

@cyberphone
Copy link
Author

Although security for the "backend" is not covered here, there are a few apparent things worth mentioning.

  • The name "Super Shop" could be a lie. The Acquirer should have the information needed to block such a transaction.
  • The domain "supershop.com" can be provided by the Acquirer as a part of the augmented AREQ sent to the Issuer. A mismatch should abort the transaction request.
  • If the Merchant changes anything in its payment claim, it will be revealed by the Issuer due to the hashing arrangement.

@cyberphone
Copy link
Author

cyberphone commented Feb 17, 2021

PaymentRequest

const methodData = [{
  supportedMethods: 'https://emvco.com/spc/visa'
},{
  supportedMethods: 'https://emvco.com/spc/mastercard'
},{  
  supportedMethods: 'https://europeanpaymentsinitiative.eu/spc'
}];

const request = new PaymentRequest(methodData,{
  id: '7040566321',   // Mandatory for SPC
  total: {label: null, amount: {currency: 'EUR', value: '435.00'}},
  payee: 'Space Shop'   // Possible API enhancement
});

const response = await request.show();
await response.complete('success');

A payment method intended for use with the SPC payment handler, would then establish this link during payment credential enrollment. This would enable merchants to either use individual "pay buttons" for each payment method, or support collections of useful methods to their liking.

SPC must obviously include a selection UI itself. Swiping credentials icons could be an option. Updated the UI accordingly...

There may be a need for payment system specific data during invocation or in payment credentials. The inclusion of such data would need to be standardized to keep SPC fully universal.

Notes:

  • There are no predefined payment methods.
  • Since this is effectively a "Payment Terminal on the Web", it should provide a consistent user experience which means that there MUST be a single PaymentItem having a label property with the argument null. A deviation MUST cause the request to be terminated with an error message. The Payee and Total UI elements SHOULD be localized.

@equalsJeffH
Copy link
Contributor

ISTM that this issue ought to more properly be filed at https://github.com/rsolomakhin/secure-payment-confirmation

@cyberphone
Copy link
Author

cyberphone commented Feb 19, 2021

@equalsJeffH it may seem like that but the fact is that mine[1] and Google's[2] takes on SPC only have the name in common.

As a thought experiment you could try to envision what users (UI-wise) would have to put up with and banks would have to build (giant central registries holding enrolled account numbers) in order to apply 3DS/step-up authentication concepts to IBAN accounts like the sample's FR7630002111110020050014382.

/Anders

1] Effectively a "technology refresh" of EMV adapted for the Web. EMV remains the to date only payment authorization scheme that enjoys both real and de-facto standards status. The https://www.w3.org/TR/payment-request/#canmakepayment-method should fully replace the need for user-hostile and privacy-impeding 3DS "step-up" methods required by the current W3C/Google proposal. @christiaanbrand @srsheth

2] Builds on leveraging two technologies that were designed for other purposes. FIDO: User authentication rather than payment authorization. 3DS: Supporting users who do NOT have access to sophisticated client-side crypto and trusted browser code which was a great idea back in 1998 when it was created.
@balfanz @ve7jtb @dturnerx

@rsolomakhin
Copy link

@cyberphone, if I understand the gist of your proposal, there appears to be two primary differences from SPC:

  1. The challenge comes from the merchant instead of the bank.
  2. The browser stores some extra data for each payment credential, so it can return user's account number, encrypted with the public key of the bank, too.

Is that a fair summary?

I think perhaps this proposal would be more clear if the enrollment step was described or specified. How would it work?

@cyberphone
Copy link
Author

cyberphone commented Feb 27, 2021

Hi @rsolomakhin, I believe the differences are much bigger.

  1. 3DS/SPC is an additional (and optional) card-holder authentication step introduced before the actual payment transaction: https://stripe.com/docs/payments/3d-secure. It is possible that Stripe's implementation does something else but the current SPC state-diagrams are pretty hard to follow so I'm not able to tell 🤔 I have not the faintest idea how SPC could deal with SEPA and similar A2A (account to account) payments.

  2. EMV is a unified and optimized single-step, "store-and-forward" payment request requiring no prior third-party interaction with issuers or handing out account numbers by users. In my take on EMV, (FIDO Web Pay), the browser would together with FIDO tokens form a universal wallet. https://github.com/rsolomakhin/secure-payment-confirmation/issues/33. Encrypted authorizations (not account numbers), is the only thing that conceptually differs from EMV but it is also the core of the idea making the system universal with respect to payment systems. That is, enabling "routing" of requests with respect to issuers to be independent of account numbers (e.g. https://mybank.fr/payment)

The differences on the browser side should be rather moderate since both concepts build on FIDO tokens and a secure browser-resident payment UI/handler. Enrollment is yet to be described but AFAICT the major difference is in the payment handler database since SPC defines a single payment method while FIDO Web Pay makes the FIDO tokens dynamically define the actual payment methods (they are just URLs), all implicitly linked to the built-in payment handler.
@dturnerx

@cyberphone
Copy link
Author

@rsolomakhin Major issues with both solutions is that:

  • Most banks already have deployed mobile payment authorization systems limiting their interest in investing in new systems that "does almost the same thing".
  • Most people still use "PCs" for shopping making QR a fairly necessary part of the plot.

FIDO Web Pay (in contrast to SPC), should be attractive for Open Banking TPPs who could finally get away from systems requiring users to select bank in order to make a purchase. Note though that Open Banking is a rather slow boat...

Personally I believe the code that is currently intended to be a part of the browser, should long-term rather be a part of the client platform because then the same scheme and "virtual cards" could be used everywhere. Such a change would be invisible to all actors.

Conclusion: there is no "low-hanging fruit" or quick wins here. However, the availability of:

  • Built in FIDO token support
  • Built in universal Payment Handler

should be of interest for all but suppliers of proprietary payment systems.

@rsolomakhin
Copy link

@cyberphone - What do you mean by a built-in universal payment handler? I wonder whether that make the browser into yet another payment app that websites have to support, a la https://xkcd.com/927/.

@cyberphone
Copy link
Author

cyberphone commented Feb 27, 2021

What do you mean by a built-in universal payment handler? I wonder whether that make the browser into yet another payment app that websites have to support

@rsolomakhin It is possible that I got this entirely wrong 🙃 but my interpretation of the SPC explainer is that:

  • SPC depends on a built-in ("hardwired") payment handler
  • SPC requires specific support not only by websites, but by acquirers and banks as well

My idea is simply making the built-in code more universal based on the assumption that user authorization of card payments and for example SEPA credit transfers do not motivate separate handlers since they (AFAICT...) only differ on account data and named method.

Although Saturn is just a PoC, I consider the concept above fully verified. The Saturn wallet does not know anything about specific payment systems and it still works with quite different backend flows. BTW, this is a yet another reason to why I couldn't use PaymentRequest for Android as intended: it only supports statically declared methods 😒 Updating manifests or apps is not an option if you want a neutral (=universal) Wallet.

Since SPC does not rely on manifests I think this proves another point of mine: the manifest system adds considerable hassles but little or no value for native mode payment handlers. TEE attestations during enrollment performs this role while OS/apps version data supplied by payment handler authorization messages cover SW updates as well.


Before rushing things you should consider that this may very well be the only shot FIDO get at payments. If there is a desire making this great technology relevant for banks, payment support is a MUST. Apparently no banks are directly involved in these discussions (they usually require NDAs), so you rather have to guess what could be needed. Enabling credit transfers is though a known feature since it is already fully established in the Netherlands and in Scandinavia. It also the target for the multi-billion Euro project known as the European Payments Initiative (https://www.epicompany.eu/). These systems are without exceptions based on mobile apps. However, they have a rather limited range geographically speaking as well as being entirely proprietary. Here lies an opportunity for FIDO/Google/W3C making a difference. @balfanz

@adrianhopebailie

@cyberphone
Copy link
Author

cyberphone commented Mar 3, 2021

If my interpretation of 3DS/SPC is correct, the following should give you an indication of the huge differences in complexity between EMV/FIDO and 3DS/SPC:
3ds

The security models are also quite different: in 3DS it is the Merchant who is the RP, while in EMV it is the Issuer which seems more logical. Unless there is some kind of communication between the ACS and the "PAY" processor, it is not clear how the Issuer can know if the User actually have been properly pre-authenticated.

@rsolomakhin @equalsJeffH

@cyberphone
Copy link
Author

cyberphone commented Mar 14, 2021

@equalsJeffH @ianbjacobs @dturnerx @rsolomakhin @nadalin @balfanz I would rather claim that whatever FIDO solution the Web Payment WG takes on it will be perceived as the "official standpoint" for the (entire of) W3C, FIDO alliance, EMVCo, and Google, which IMO motivates an extended discussion. BTW, I have now cleaned-up the "spec" above (it has numerous of flaws): https://fido-web-pay.github.io/ It might be worth knowing that it does things not even Google and Apple Pay can do 😁 As expressed on LinkedIn in a somewhat market-ish way:
FWP


This specification has though a serious drawback: it would (if getting traction) put W3C in a difficult position requiring constant updates in order to remain competitive with the App world. This requires extending the scope to PoS and P2P. This is actually no problem at all, you just move the FWP implementation down into the platform layer which also has huge advantages for users and browser vendors since there would only be a single (system-wide) FWP "Wallet".

SPC would not require anything like that since it is virtually impossible to extend.

@rsolomakhin
Copy link

@cyberphone wrote:

I would rather claim that whatever FIDO solution the Web Payment WG takes on it will be perceived as the "official standpoint" for the (entire of) ...

At this stage, perhaps it would be more accurate to state that the organizations are exploring the benefits of FIDO through discussions and experimentation.

@cyberphone
Copy link
Author

cyberphone commented Mar 15, 2021

Yes @rsolomakhin, the mentioned organizations may have had discussions but the results of these have not been made public.

You probably do not agree, but I consider the combination of

  • FIDO
  • PaymentRequest
  • Browser-resident payment handler

as W3C's last (and certainly the best) chance moving the payment industry forward. That is, the stakes are sky-high!

Although I'm just a WPWG mailing-list subscriber, I get the impression (by reading the minutes) that everything else is pretty much on hold making SPC a likely "default".

@equalsJeffH
Copy link
Contributor

On 2021-03-17 call:
The WG consensus is that these payments-oriented discussions are not relevant to the webauthn WG and belong elsewhere, e.g., https://github.com/w3c/payment-request/issues and/or https://github.com/rsolomakhin/secure-payment-confirmation/issues

@cyberphone
Copy link
Author

@equalsJeffH @emlun @nadalin The raised issues are not related to the PaymentRequest API since nothing new is requested. Filing an issue on the Secure Payment Confirmation (SPC) project that effectively suggests dropping the idea altogether would be pretty strange. This is clearly a charter question involving not only the W3C, but the FIDO alliance, the Chromium team, and EMVCo as well.

Unlike SPC, Google pay is (with respect to the user) an end-2-end secured solution and it even encrypts authorizations.

I wish you and the W3C luck with the project "Making 3D Secure great again" 🤣

Leaving the topics here
/Anders

@cyberphone
Copy link
Author

cyberphone commented Dec 24, 2021

The requirements imposed by SPC makes SPC an integral part of a revised WebAuthn charter, otherwise SPC would simply put not work. Some of the proposals aired, even affect FIDO/CTAP.

Before you add SPC to the WebAuthn charter, I would suggest taking a peek at mozilla/standards-positions#570 (comment) which summarizes the somewhat voluminous data above, into a short table, which also includes a comparison with Apple Pay.
@YubicoDemo @nadalin @ve7jtb @selfissued

To date unresolved SPC issues include:

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

No branches or pull requests

5 participants