PPS 3D-Secure API

(0 reviews)

HMAC

This page describes the details of the HMAC Authorisation for both incoming and outgoing requests.

Why to use HMAC ?

It is being used to make possible to the recipient of requests to be able to verify that the request has come from a known source, and has not been tampered with in-transit.

How to use it ?

When sending a request, the client must generate for it HMAC string using the algorithm described in this document and then attach it as value of Authorization header to the request. On receiving the request, the server (recipient) must generate the HMAC string for it (so with the use of the same algorithm and the same data as customer) and compare if they are equal. If they are not then received request should be rejected with a 401 Unauthorized response. Core of the algorithm is securely stored and shared between PPS and customer secret key which is a randomly generated series of bytes.

Before being able to integrate with the PPS APIs secured by HMAC Authorisation, the username and associated shared secret must first be set up by PPS, after which we will share these credentials securely with the customer.

How HMAC Algorithm looks like ?

The algorithm documented here is identified as PPS-HMAC-1 which is provided in the Authorization header, to identify the algorithm use. There may be other variants added in future. Pseudo-algorithm for producing the HMAC header:

//md5 hash of payload (hex-encoded)
//if the payload is empty - e.g. a GET - payloadMd5 should be null
payloadMd5 = md5(payload)

//build input string for Hmac generation
inputString = "<customerCode>+<username>+<httpMethod>+<resourcePath>+<timestamp>+<nonce>"
if payloadMd5 != null
  inputString += "+<payloadMd5>"

//generate Hmac using SHA256 hashing algorithm
hmacString = hexEncode(hmacSHA256(sharedSecretBytes, inputString))

//set Authorization header with "hmac" prefix, and providing the public inputs used for regeneration, along with the actual HMAC
authHeader = "hmac PPS-HMAC-1;<customerCode>;<username>;<timestamp>;<nonce>;<hmac>"

The MD5 hash of the payload must be of the exact payload sent / received. Any modification of the payload, after an HMAC is generated or before it is validated, will almost certainly cause the HMAC to not be valid. This includes any whitespace characters, line breaks etc.

HMAC Generation

When sending a new request, to be authorised by HMAC, the new HMAC needs to be generated (retries are not considered a 'new' request, the same HMAC may be used). Certain properties to be used in the HMAC generation are already known, and some are to be introduced as part of the HMAC Generation process. Consider the new request to be made:

PUT https://pps-customer-host.com/test/3d-secure/api/v1/authorisation-challenges/12345-67890-12345
{
  "id": "cb709bc2-f7ed-49b0-a3b1-8fa4c65ac55d",
  "source": "APATA",
  "request_date": "2019-06-14T13:23:18Z",
  "expiry_date": "2019-06-14T13:28:18Z",
  "customer_code": "9123456789"
}

where..

  • pps-customer-host.com/test is the URI registered with PPS for sending the request to. (could also be just pps-customer-host.com )
  • /3d-secure/api/v1/authorisation-challenges/12345-67890-12345 is the PPS-defined resource, in this case, identifiying a specific “authorisation challenge”, by it’s “id” - 12345-67890-12345
  • Customer Code - The PPS Customer Code - for example: 9123456789
  • Username - The username for the HMAC generation. This is paired with the shared secret, so this is effectively just a reference to the Shared Secret to use - for example: my-username
  • Shared Secret - Secret key used in the HMAC generation, known only by sender and recipient. In this case the example shared secret is representable as an ASCII string, but in reality may contain many bytes that cannot do not correspond to ASCII characters. As a result, the secret would typically be transmitted encoded (e.g. in Hex or Base64), for example: mysharedsecret123
  • HTTP Method - The HTTP Method for the request, to the Request URI - for example: PUT
  • PPS Resource Path - The path to the PPS resource in the request. This does not include the hostname or the rest of the customer URI. for example: /3d-secure/api/v1/authorisation-challenges/12345-67890-12345
  • Payload MD5 hash - MD5 hash of the actual (and exact) payload of the request to be sent, hex-encoded. This is used in the HMAC, so that if the call is intercepted, the payload itself cannot be tampered with, without re-generated a new HMAC. For requests where there is no payload, for example GET requests, then this should be passed into the algorithm as null This alphabetic characers in the md5 hash must be in lowercase, not uppercase. for example: 9682f02fb48379e2d7b9a3b475a65c74

We also require the following additional pieces of information to be used in the HMAC Generation algorithm:

  • Timestamp - A timestamp representing “now” should be generated. This will be passed in the Authorization header, so that it can be re-used by the recipient when regenerating the HMAC. This will be used as, and trasmitted as, an ISO 8601 datetime. for example: 2020-02-06T13:10:56Z
  • NONCE word - This will be a randomly generated word (could also be a number), that must not be re-used for any other HMAC (except in retries of the same request), which is also passed in the Authorization header.
  • It is recommended to use a UUID (Version 4) for this, as a simple mechanism for generate a unique string. for example: 5b1597e3-d03f-4436-b1eb-e98c9859c584

HMAC Verification

To verify a received HMAC, the same steps as above should be followed to regenerate the HMAC based on the request being made, and the details received encoded in the HMAC header, where the inputs for the HMAC regeneration are extracted from the Authorization header, generated from the received request uri, http method and body, and using the shared secret (not transmitted). The shared secret should be the same used in the generate procedure - which should be stored securely.

When implementing the HMAC verification, please ensure that:

  • the timestamp expiry window is set to 5 minutes, in either direction. Any timestamp outside of that should be rejected.

  • there is a method of obtaining/storing a nonce value to ensure uniqueness of the nonce and that repeated values for different requests are rejected as invalid

Online Resources

The following tools can be used to aid with the development of the processes above as well as acting as a validation tool to ensure you are generating values that match:


Reviews