Skip to content

encrypted_card

Olivier Yiptong edited this page Sep 5, 2017 · 32 revisions

Encrypted Card Payment Handler

Overview

This document describes a proposal for a payment handler that behaves like basic card, but provides additional security, by ensuring that the card information is not transmitted in the clear to the merchant.

This reduces PCI scope for the merchant, especially v3+

Payment Handler Properties

We'd like to consider this colloquially as "BasicCard++". In that sense, there are a few things that a similar to BasicCard and a few differences.

Similarities:

  • Form Fills are used to populate payment instruments
  • Payment Request invocation is similar

Differences:

  • The PAN is encrypted following an exchange with a vault provider
  • The returned value from the PaymentRequest API does not contain the PAN, but contains an opaque blob
  • The returned blob can only be used to process the transaction with the vault provider that created it
  • Additional constraints may be put by the vault provider on the blob (could be a nonce, time bounded, or permanent)

image

PaymentMethodData Specification

The payment handler can be specified using the same syntax as BasicCard with a notable difference: a vault provider will be specified.

This parameter will be provided in addition to those specified in basic-card:

dictionary EncryptedCardRequest {
             sequence<DOMString>       supportedNetworks; // Defined in Basic Card
             sequence<CardType>        supportedTypes; // Defined in Basic Card
    required DOMString                 encryptionProviderURL;
};

The Javascript would look as follows:

var supportedInstruments = [
  {
    supportedMethods: ['encrypted-card']
    data: {
      supportedNetworks: ['amex', 'discover', 'mastercard', 'visa'],
      supportedTypes: ['credit', 'debit'],
      encryptionProviderURL: 'https://www.bobpay.com/encrypted-cards'
    }
  },
  ...,
];
var payment = new PaymentRequest(
  supportedInstruments,
  details,
  options
);

Card Encryption

The exact same data contained in the BasicCardResponse dictionary, is encrypted.

dictionary EncryptedCardResponse {
    required DOMString       cardNumber;
             DOMString       cardholderName;
             DOMString       cardSecurityCode;
             DOMString       expiryMonth;
             DOMString       expiryYear;
             PaymentAddress? billingAddress;
};

The (asymmetric) encryption can occur in one of two ways:

  1. through the origin's SSL public key if a manifest is not found or the parameter is not found in the manifest
  2. through a Web App Manifest parameter, specifying a public key and list of ciphers

There's an inherent advantage to using 1. because if there has already been a cipher exchange, the public key is potentially in the Browser's cache, and the result of the TLS handshaking will have selected a cipher suite for the key exchange. The same cipher suite can be used to encrypt the card data.

The card data is then encrypted and represented as a base64-encoded string.

PaymentRequest Response

This data is returned as part of the PaymentResponse as follows:

dictionary EncryptedCardResponse {
             DOMString       cardholderName; // data from BasicCardResponse
    optional DOMString       suffix; // Last four digits of card number
    required DOMString       encryptedCardData; // base64-encoded string
};
Clone this wiki locally