Digital Interface Payload

Introduction

This document describes the format of EML's Digital Interface Payload (DIP). It is an encrypted payload which is used to convey card security details for a specific account. It is used in conjunction with the provisioning of virtual/digital card products.

The payload contains all of the details necessary to successfully complete a card not present (CNP) transaction with that account. Namely, it contains:

  • Card Number (PAN)
  • Expiry Date
  • Security Code (CVV2)

Accessing these details involves a simple, on-line, cryptographic exchange between EML and your application. The following sections describe the procedure for this exchange, and the steps required to decrypt and decode the payload.

Source APIs

EML has two different APIs which provide access to the DIP exchange. Both of these APIs accept the same parameters and return the DIP payload in the same format.

  1. EML Web Services 2.0 (SOAP) API
    • See GetAccountDipRequest in the Web Services 2.0 documentation.
    • Normal username/password authentication applies to this request.
  2. EML Web Services 3.0 (REST) API
    • See POST /accounts/{id}/dip in the Web Services 3.0 documentation.
    • Normal OAuth token authentication applies to this request.

Identifiers and Keys

EML has a registry of mobile/web applications which use DIP integration. Before you can complete a DIP exchange, you need to register your application with EML. We will provide you with a UUIDopen in new window for your application, which we refer to as the ApplicationId.

Each application has one or more application keys. Each key is comprised of a 256-bit pre-shared symmetric key, which we refer to as ApplicationKeySecret. This secret is never transmitted over an EML API. Each key also has a UUID, ApplicationKeyId, used to refer to that specific key without needing to disclose its secret.

Application

Key rotation

We expect that DIP decryption will happen as close to the user as is practical. For example, for a mobile application, the application key might be packaged into the application binaries deployed to the user's device.

Having multiple keys per application allows you to rotate keys on a regular basis while providing a grace period for older keys. For this to function correctly, your ApplicationKeyId must be unique for each new key.

Requesting a DIP

The following diagram illustrates the sequence of events for the requesting and decrypting the DIP.

DIP Request and Response

Generating an EmphemeralKey

For each request for a DIP exchange, you should generate a random, single-use, 256-bit ephemeral key. Where available, you should utilise secure sources of entropy to generate your key.

Performing an EML API Request

The requirements for the API request vary depending on whether you are using the Web Services 2.0 (SOAP) API or the Web Services 3.0 (REST) API. See the relevant documentation for each API to confirm your requirements.

Both APIs minimally accept the following arguments:

  • The ExternalAccountId of the account to get the card security details from
  • The ApplicationId of your application
  • The relevant ApplicationKeyId for the current user/version
  • The randomly generated EphemeralKey for this request

The following is an example of a simplified request from the Web Services 3.0 API.

// POST: /accounts/YCL80C2SW/dip
{
  "application_id": "4bdb92b7-e22e-4012-aed4-9276ec67ead7",
  "key_id": "d7d5b030-e94f-43f7-942d-3d6703236b84",
  "ephemeral_key": "pwmbH/7quy8Jo0YtcPqz8oRqD53WCa4cHDaKkYueBLk="
}

Decrypting and Decoding the DIP

The following diagram illustrates the process of decoding and decrypting the DIP.

Decode and Decrypt

Decoding a byte sequence from Base64

The DIP is transmitted using Base64open in new window encoding. The first step of decoding is to reverse this encoding and produce a byte sequence. A standard, non-variant, RFC 4648open in new window compliant Base64 encoding is used.

Checking the PayloadVersion

Once you have reversed the Base64 encoding, you can examine the first byte in the resulting byte sequence, the PayloadVersion byte. This is an 8-bit unsigned integer value, which has the expected value of 1. Values of 2 through 255 are reserved for future versions of the DIP specification. Future versions may use an alternative decryption/decoding procedure, so you should abort decoding if the PayloadVersion does not match the expected value.

Deriving the PayloadKey

The final DIP is encrypted using a 256-bit PayloadKey, derived from the EphemeralKey and ApplicationKeySecret. We utilise a SHA-256 HMACopen in new window to derive the key.

PayloadKey = HMAC_SHA256(data: EphemeralKey, key: ApplicationKeySecret)

Decrypting with AES-256

We use the Advanced Encryption Standard (AES) to encrypt the DIP. To decrypt the payload, you need to use a compatible AES implementation along with the following parameters:

  • Key: 256-bit PayloadKey
  • IV: 128-bit random IV generated by EML
    • Contained within bytes 1:16 of the DIP payload.
  • Cipher Text: The encrypted account data
    • Contained within bytes 17:48 pf the DIP payload
  • Mode: CBC
  • Padding mode: PKCS#7 (also PKCS#5 compatible)

Format of the Decrypted Data

Once the DIP is decrypted, you are left with a 27 byte sequence containing the card security details. This byte sequence is a text string, which you can be decode with either UTF-8open in new window or ASCIIopen in new window character encoding.

The text string contains the following elements, separated by semicolons (;).

  1. The 16 digit card number (also known as PAN)
  2. The 6 digit card expiry date, month and year, formatted as mmyyyy.
  3. The 3 digit card security code (also known as CVV2)

The string is always exactly 27 characters, and it contains no whitespace characters.

An example decoded string is shown below:

4000000000000001;102018;999

// Card Number = 4000000000000001
// Expiry Date = October 2018
// Security Code = 999