Skip to content

Signatures

mattsaxon edited this page Jan 5, 2018 · 6 revisions

This is a proposal for digitally signed request data to prevent malicious actors from tampering with payment request data that is passed in the clear. An example of this would be tampering with a the request data of a push payment to subvert a payment, potentially without the merchant becoming aware until sometime later (e.g., during settlement).

Any tampering would be detectable by payment handlers verifying the signature.

High Level Proposal

  • Each payment method defines which request fields (if any) must be signed.
  • These fields are signed by the requestor with a private key (either the merchant's or their processor's); the corresponding public key is provided in the request via a certificate.

Example

Pre signing

  { 
    supportedMethods: "https://example.com/bobpay",
    data: {
      dataToBeSigned: {
        merchantIdentifier: "XXXX",
        bobPaySpecificField: true
      },
      unsignedData: {...},
      dataSecurity: {
        signatureCertPath: "public.pem"
      }
    }
  }

Post signing

  { 
    supportedMethods: "https://example.com/bobpay",
    data: {
      unsignedData: {...},
      dataSecurity: {
        signature: {...},
        signatureCertPath: "public.pem"
      }
    }
  }

Data Model

  • dataToBeSigned includes those request fields that must be signed according to the payment method.
  • unsignedData includes the request fields that are not signed. This list is mutually exclusive of signedData.
  • signature is a JOSE JWS signature using JWS JSON Serialization.
  • signatureCertPath designates a certificate that includes the requestor's public key. It is a (URL) path relative to the origin of the requestor (whether merchant or provider).

Additional Considerations

  • Each data object may be be signed with a different key.
  • The model may be extended to allow payment methods to define that some response fields must be signed by payment handlers.
  • Payment handlers could display the identity of the certificate issuer to enhance user confidence.
  • Payment handlers could alert users when the certificate issuer does not fulfill some trust criterion. For example, if not a registered issuer verified as a Swift Legal Entity.
  • While the details of signature and encryption lie outside the scope of this proposal, the proposal has been designed to faciliate reuse of libraries.
  • Signatures may only be necessary or useful for some payment methods, e.g. push payments.

Preventing Tampering of the responseEncryptionKey

To prevent tampering of the responseEncryptionKey we use a "double envelope" approach:

Example

Pre signing

  {
    supportedMethods: "https://example.com/bobpay",
    data: {
      dataToBeSigned: {
        plainData: {
          merchantIdentifier: "XXXX",
          bobPaySpecificField: true
        },
        dataSecurity: {
          responseEncryptionKey{...}
        }
      },
      unsignedData: {...},
      dataSecurity: {
        signatureCertPath: "public.pem"
      }
    }
  }

Post Signing

  {
    supportedMethods: "https://example.com/bobpay",
    data: {
      unsignedData: {...},
      dataSecurity: {
        signature: {...},
        signatureCertPath: "public.pem"
      }
    }
  }