Security

There are number of security layers to make the communication between our servers as secure as possible. It is strongly reccommended to introduce the following measures to your integration.

JWT based authentication

Before using the JWT based authentication, you will need to add a public key under "API keys" section in your Fortumo Dashboard. Refer to Preparing SSH keys guide on how to generate the public and private key pair.

We strongly advise you to use one of available JWT token libraries as this significantly simplifies token generation and helps in avoiding common mistakes. Refer to JWT.io for a full list of available libraries for each programming language

JWTs are composed of three parts - header, payload and signature. JWT header identifies the algorithm that is used for generating the token signature. Fortumo currently supports tokens signed with RS256 algorithm, so the header of the decoded JWT should always be following:

1
2
3
4
{
  "alg": "RS256",
  "typ": "JWT"
} 

In the payload section we expect you to specify the issuing (iat), not before (nbf) and expiration (exp) time of the token. Every timestamp needs to be in Unix epoch format, so an example payload could be:

1
2
3
4
5
6
7
8
9
{
  "iss": "d3ad608d0a1729727a3eb6bc0892b427", 
  "exp": "1988326400", 
  "sub": "hdcb", 
  "aud": "Fortumo",
  "nbf": "1485256642",
  "iat": "1485256645",
  "jti": "00001"
} 

JWTs are signed with the private key of your RSA key pair, so the final part of the decoded JWT will be in following format:

1
2
3
4
5
6
RSASHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  [public_key],
  [private_key]
)

After you have completed generating a unique token for your request, simply add the token value in your request Authorization header.

1
Authorization: Bearer {JWT} 

Full headers example:

1
2
Content-Type: application/json
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJleHAiOjE ... CJhbGciOEgVU0U4vvGg_a2rCP6XHQ
Putting it all together

Now that you have successfully also signed the token, you can use the token for initializing a payment. As explained above, every JWT that you will be including in the payment initialization URL has a following structure: header.payload.signature. Therefore from our example the payment initialization URL format would be: http://dcb.fortumo.com/{merchant_id}/?token={header.payload.signature}

Nifty website to learn more about JWTs and how to put them together is available here: https://jwt.io

Extra security to validate the callbacks made by Fortumo

Whitelisting our server IP addresses

For additional layer of security you can also whitelist IP addresses Fortumo is using for initiating callbacks. To get the list of IP-s please contact your integration manager.

If your security policy requires strict checking of the certificate issuer authority then please contact your account manager. Please also test your endpoints with unauthorised requests in order to make sure the verification layer is working as intended.

Validating signature in callback header

Each notification sent to your server includes http header X-Fortumo-Content-Signature and it's value will be describing the request contents in the form of a JWT token. Parsing the JWT will result in the following parameters:

1
2
3
4
5
6
7
{
  "iss": "api.fortumo.com",
  "iat": 1536766126,
  "exp": 1539358126,
  "body_sha256": "0321385d3f67571815efebbb377a6fe9d2b4e205a87f3d5867de60b152560322",
  "key_signature": "26:bc:af:13:1a:f2:c6:bc:96:75:d6:ad:f0:50:e3:7c"
}

To validate the requests you will have to follow these steps:

  1. Read key_signature parameter which indicates the key Fortumo is using for signing JWT
  2. Validate signature of the JWT
  3. If signature is correct then calculate sha256 hash of the notification request body and validate against body_sha256 parameter

Signature in callback header is an opt-in feature. In order to enable it for your callbacks and get the public key from Fortumo please contact your account manager.

Help us improve our Merchants Portal. Was this article helpful?