Authentication

An introduction to the different API authentication methods used with Bluefin's P2PE Manager.

All API calls to the P2PE Manager require authentication. It can be faster to get started with Basic authentication but the hash-based message authentication code (HMAC) method is a more secure solution. HMAC provides replay protection, time-to-live, and request integrity, and we require it for the production environment, as we do with Decryptx.

Basic Authentication

Basic authentication is a simple authentication scheme built into the HTTP protocol. Our Management APIs support Basic authentication constructed from the usernames and passwords from the P2PE Manager. You send an HTTP request with the authorization header that contains the word Basic, followed by a space and a base64-encoded string username:password.

To build a Basic authentication header, include your P2PE Manager credentials. For example, if your P2PE Manager username and password are user and password the authentication header is as follows:

  1. Concatenate your user and password with a : separator.

    user:password

  2. Base64 encode the string:

base64Encode( user:password )

//output dXNlcjpwYXNzd29yZA==
  1. Build the Basic authentication header:
Authorization: Basic dXNlcjpwYXNzd29yZA==

Example:

curl 'https://192.168.33.40:3110/api/v1/transactions?&take=2&skip=0' \
    -X GET \
    --header 'Content-Type: application/json' \
    --header 'Accept: application/json' \
    --header 'Authorization: Basic dXNlcjpwYXNzd29yZA=='

HMAC Authentication

The HMAC method provides replay protection, time-to-live, and request integrity. Our implementation requires that you use the sha-256 and hmac-sha-256 hashing algorithms. Before you can implement this auth method, you must have a shared key. If you were not given a shared key when you registered, please request one from Bluefin Support.

An HMAC authentication header must contain the following properties:

Property Description
username This property must be set to your username.
nonce This property must be set to a nonce. A nonce is a unique random string. If a nonce is encountered more than once during a 15 minute period the API call is rejected. It is your responsibility to ensure that the nonce is unique.
timestamp A unix timestamp. Our service will reject API calls with a timestamp older than 15 minutes.
response The response property is a HMAC-SHA256 hash (in hexadecimal format) of a number of the API call's properties. See the section on building the String-to-Hash, below, for a detailed description of string that must be included in the hash. Once you have the StringToSign, generate the response like this: Hex( HMAC-SHA256( sharedKey, StringToHash ) );

Build an HMAC Authentication Header

  1. Generate a nonce:
1l5daa1ju1b7lmljc5p4nev0ve
  1. Generate a unix timestamp:
//In JavaScript/Node.js
Math.round(new Date().getTime()/1000)
//output 1489574949

//In Java
(int) (System.currentTimeMillis() / 1000L)
//output 1489574949
  1. Generate the content hash by SHA-256 hashing the request body:
\n represents a newline character and \t represents a tab character.

sha-256({
            "name": "The Tired Window",
            "cardConexId": "001J000001oiXle",
            "mid": "220614971581",
            "isActive": true,
            "directPartner": {
                "id": "string",
                "name": "string"
            },
            "location": {
                "name": "The Tired Window Headquarters",
                "nameOfBusiness": "The Tired Window",
                "locationType": "Corporate Headquarters",
                "uniqueId": "53e1537f-2fef-49a2-a6da-8678a7066e94",
                "country": {
                    "code": "US"
                },
                "address1": "43 Sesame St",
                "address2": "Suite 40",
                "city": "Tulsa",
                "stateProvince": "Oklahoma",
                "postalCode": "74120",
                "mailCountry": "United States",
                "mailAddress1": "43 Sesame St",
                "mailAddress2": "Suite 40",
                "mailCity": "Tulsa",
                "mailStateProvince": "Oklahoma",
                "mailPostalCode": "74120",
                "notes": ""
            },
            "contact": {
                "userName": "dbackler3",
                "firstName": "Dora",
                "lastName": "Backler",
                "email": "[email protected]",
                "phone": "687-251-0960",
                "userRole": "Client Admin",
                "isActive": true,
                "sendWelcomeEmail": false
            }
        })

//output cd3d3c1ca4a4ad85b442ed6b71bb71aba6e175c493a3d290c1b17ac0234b7c99
  1. Build the String-to-Hash:

The String-to-Hash is composed of the elements described in the table below .When creating the String-to-Hash, it is important that you follow the format exactly as described below, or the request will be rejected.

Element Description
HttpVerb Should be set to 'POST' for all API calls.
CanonicalizedResource Should be the HTTP Request URI, without protocol, port and domain parts; the following list outlines the appropriate value for each endpoint:
  • validate partner = /api/partner/validate
  • validate device = /api/v1/device/validate
  • process payload = /api/decrypt/parser
nonce Same value as set in the auth header nonce property.
timestamp Same value as set in the auth header timestamp property.
ContentHash A SHA-256 hash in hexadecimal format of the HTTP POST's body. Our service expects you to hash the whole body, including any leading and trailing whitespaces that you may have included. See Step 3, above.
\n The Unicode code point U+000A, commonly called newline).

The String-to-Hash is composed of these elements in this exact format. Once you have the String-to-Hash, pass it into the HMAC-SHA256 hashing algorithm to generate the HMAC authentication header's response property.

HttpVerb + " " + CanonicalizedResource +
				"\n" + nonce + "\n" + timestamp +
        "\n" + "\n" + ContentHash;

For our example the String-to-Hash is:

"POST /api/v1/clients\n1l5daa1ju1b7lmljc5p4nev0ve\n1489574949\n\ncd3d3c1ca4a4ad85b442ed6b71bb71aba6e175c493a3d290c1b17ac0234b7c99"
  1. HMAC-SHA256 hash the String-to-Hash with the secret key:
Hex( HMAC-SHA256( 'mypassword', "POST /api/v1/clients\n1l5daa1ju1b7lmljc5p4nev0ve\n1489574949\n\ncd3d3c1ca4a4ad85b442ed6b71bb71aba6e175c493a3d290c1b17ac0234b7c99" ) )

//output 6ab4b74f3c4d96b04cfca660f046813cacbf95a3e9540ad3970f22da1ec07262
  1. Build the Digest authentication header
Authorization: Hmac username="myusername",
  nonce="1l5daa1ju1b7lmljc5p4nev0ve",
  timestamp=1489574949,
  response="6ab4b74f3c4d96b04cfca660f046813cacbf95a3e9540ad3970f22da1ec07262"

Example:

curl 'https://secure-cert.decryptx.com/api/partner/validate' \
    -X POST \
    --header 'Content-Type: application/json' \
    --header 'Accept: application/json' \
    --header 'authorization: Hmac username="myusername", nonce="1l5daa1ju1b7lmljc5p4nev0ve",  timestamp=1489574949, response="6ab4b74f3c4d96b04cfca660f046813cacbf95a3e9540ad3970f22da1ec07262"' \
    -d '{
                    "name": "The Tired Window",
                    "cardConexId": "001J000001oiXle",
                    "mid": "220614971581",
                    "isActive": true,
                    "directPartner": {
                        "id": "string",
                        "name": "string"
                    },
                    "location": {
                        "name": "The Tired Window Headquarters",
                        "nameOfBusiness": "The Tired Window",
                        "locationType": "Corporate Headquarters",
                        "uniqueId": "53e1537f-2fef-49a2-a6da-8678a7066e94",
                        "country": {
                            "code": "US"
                        },
                        "address1": "43 Sesame St",
                        "address2": "Suite 40",
                        "city": "Tulsa",
                        "stateProvince": "Oklahoma",
                        "postalCode": "74120",
                        "mailCountry": "United States",
                        "mailAddress1": "43 Sesame St",
                        "mailAddress2": "Suite 40",
                        "mailCity": "Tulsa",
                        "mailStateProvince": "Oklahoma",
                        "mailPostalCode": "74120",
                        "notes": ""
                    },
                    "contact": {
                        "userName": "dbackler3",
                        "firstName": "Dora",
                        "lastName": "Backler",
                        "email": "[email protected]",
                        "phone": "687-251-0960",
                        "userRole": "Client Admin",
                        "isActive": true,
                        "sendWelcomeEmail": false
                    }
                }'

RSA Authentication

Generate RSA Key Pair

The following section outlines the steps involved in generating an RSA key pair with OpenSSL. We recommend that you generate a 2048 bit key pair as 1024 bit keys are no longer considered secure and 4096 bit keys consume considerable CPU resources when signing API calls.

  1. Generate a 2048-bit RSA private key and write it to a file private.pem
#Output an RSA private key with 2048 bit protection.
openssl genrsa -out private.pem 2048
  1. Generate a PKCS8 formatted file from the private key and write it to file private8.pem. The private8.pem file must be used in the RSA-DIGEST function to sign the requests.
#Generate a pk8 file from the private key.
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in private.pem -out private8.pem
  1. Generate the public key file from the private key and write it to a file public.pem.
#Generate a public key from the private key.
openssl rsa -in private.pem -outform PEM -pubout -out public.pem

Authentication Header Guide

The RSA authentication method is almost identical to HMAC. The only difference is that it uses an RSA private key to sign the String-to-Hash and a RSA public key to validate that the signature is valid. RSA keys provide a more secure way of signing your auth headers than using a password. While a password can eventually be cracked with a brute force attack, RSA keys are nearly impossible to decipher by brute force alone. The downside of using RSA to sign API calls, is that RSA signatures require a lot more CPU resources (up to ~250 times) than HMAC hashing.

Our Generating an RSA key pair guide outlines how you can create a public and a private key. You must send the public key to Bluefin, and keep the private key on your server.

PropertyDesecription
username This property must be set to your partnerID.
nonce This property must be set to a nonce. A nonce can be any arbitrary string, however each nonce can be used only once over a 15 minute period. Our service keeps a record of these nonces; if a nonce is encountered more than once during a 15 minute period the API call is rejected and an auth error response is produced. It is up to you to keep the nonce unique.
timestamp A unix timestamp. Our service will reject API calls with a timestamp older than 15 minutes.
response The response property is an RSA private key signature of a number of the API call's properties.