1. A Word of Caution

Throughout this article we point to https://jwt.io as a third-party service to validate tokens. Please be mindful that validating production tokens over the web is highly risky.

For sensitive tokens, you should consider validating them directly on the SSP ATM service, or with an offline tool such as Notepad++.

Other alternatives such as the JWT Debugger Chrome extension also exist.

Analyzing the token's code prior to using it to understand the level of exposure it represents is highly recommended.

2. Download Token Generator

3. Introduction

License requests to the SSP are done using JSON Web Tokens (https://jwt.io/introduction/).

JSON Web Tokens are always signed using credentials that Nagravision provides to each customer. Some token types are additionally encrypted.

The Token Generator tool allows to generate signed and encrypted JWT tokens and its code serves as a reference implementation for partners and providers that wish to integrate with our SSP platform.

3.1. Configuration and Usage

Unzip token-genrator.zip and go into the base directory, which should look like this:


Open the file config/config.json and set the token type (field token_type) to one of the supported token types (ie. "ContentAuthZ", "Kc", "AuthN", "ECMAuthZ", "DevAuthN", "Session")

{
 "app_config": { 
 "token_type": "ContentAuthZ", 
 "key_path": "key.json" 
 } 
}

Token payload examples for each token type are pre-configured and included in config folder.

Json schemas of the token payload are available in the json-schema directory.

Set the 'exp' field in each token body supporting it in order to indicate the expiration date (epoch in seconds) of the generated token.

3.2. Configuration Options

Available options are:

token_type: type of the target token to be generated. It will be used to resolve which token payload to be used as a template.

key_path: path to the credential signing and encryption keys to be used for signing and encryption.

token_output_dir: By default system writes the token in /token directory, which can be overridden to other suitable location by changing this attribute. Path must be absolute path if it is outside of the project setup.

In order to update the json files please find the documentation of the token formats here: SSP Tokens Reference.

3.3. Credentials

Credentials are used to sign and encrypt JWT tokens to validate that the tokens were created by an authorized tenant and to protect the content keys.

Example credentials are already available in file key.json in the base directory. Please update them in case you received different credentials.

3.4. Requirements

This API is developed using Java 1.8 and Eclipse IDE 4.2 (Luna). Make sure to have Java 1.8 installed on platform. You can use the IDE of your choice but by using Eclipse the project can be directly imported in Eclipse's workspace.

4. JWT Token Generation

In order to generate the token please run the run.bat, for example by double clicking it in the windows explorer.

This will open a command shell showing the execution logs:


The generated tokens can be found in the token directory:


The generated file contains a JWT token. To inspect the tokens in the generated .tkn files you can use the website https://jwt.io.

Here is an example for an encrypted content key token, that was copied from a generated .tkn file and pasted to jwt.io in the Encoded text field on the left:


Please note that the payload cannot be seen because the token is encrypted. Here is an example of a signed authorization token, also showing the payload:

4.1. Using Token Generator Within an Application

You may integrate token generator in your application using either Java or Groovy. Here are two examples to create tokens using Groovy scripts:

4.1.1. Authorization Token (ContentAuthZ)

4.1.1.1. Code

import com.nagra.tg.client.TGClient
def authorizationToken_claim = """{{
  "typ": "ContentAuthZ",
  "ver": "1.0",
  "exp": 1659836800,
  "contentRights": [
    {
    "contentId": "VOD-CONTENTID1",
    "usageRulesProfileId": "Test"
    }
  ]
}

"""
def signingKeyId  = '176006'
def signingKeyB64 = 'vfkQEFzT8LUJbtnkusQAnx024OZHx2ygvRPs8LmENV4='
print new TGClient().generateToken(authorizationToken_claim,
signingKeyB64, signingKeyId)

4.1.1.2. Result

> groovy -cp tg.jar scripts\contentauthz.groovy
[INFO] 2016-10-11 15:26:21,107 - com.nagra.tg.client.TGClient.generateToken - 200:Success
[INFO] 2016-10-11 15:26:21,113 - com.nagra.tg.client.TGClient.generateToken - Token Written Successfully
[INFO] 2016-10-11 15:26:21,113 - com.nagra.tg.client.TGClient.generateToken - END: NagraTokenGen stops.
eyJraWQiOiIxNzYwMDYiLCJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ2ZXIiOiIxLjAiLCJ0eXAiOiJDb250ZW50QXV0aFoiLCJkZXZp
Y2UiOnsiZGV2aWNlVW5pcXVlSWQiOiJwcm0uREkudW5pcXVlLWlkIiwiaXBBZGRyZXNzIjoiMTYyLjAuMTA1LjUzIiwibW9kZWwiOiJQaG9uZV
guWSIsImRybSI6IlBSIiwiYWNjb3VudElkIjoiMjMxMzUifSwianRpIjoiMTM1MzE2IiwiY29udGVudFJpZ2h0cyI6W3siY29udGVudElkIjoi
Q29udGVudCMxIiwiZW5jcnlwdGlvbk1ldGhvZCI6IlJBV19BRVNfMTI4X0NUUl9DRU5DIiwic3RhcnQiOiIyMDE2LTAxLTAxVDEyOjAwOjAwWi
IsImVuZCI6IjIwMTgtMDEtMDFUMTI6MDA6MDBaIiwiZHVyYXRpb24iOiI3MjAwIiwic3RvcmFibGUiOiJmYWxzZSIsImRlZmF1bHRLY0lkcyI6
WyJmZmZmZmZmZi1hYWFhLWJiYmItY2NjYy0wMDAwMDAwMDA1MDEiLCJmZmZmZmZmZi1hYWFhLWJiYmItY2NjYy0wMDAwMDAwMDA1MDIiXX1dfQ.
ozBmuAIefhoiUhbiUUwTk_u5RSfJp81tGC9CLTGB7Gw

4.1.2. Content Key Token (Kc)

4.1.2.1. Code

import com.nagra.tg.client.TGClient
def contentKeyTokens_keys = '''{
    "typ":"Kc",
    "ver""1.0",
    "keys":
    [{
      "kcId""ffffffff-aaaa-bbbb-cccc-000000000501",
      "value""10AIkMpJKJfC8vXacMI1Sg=="
    },
    {
      "kcId""ffffffff-aaaa-bbbb-cccc-000000000502",
      "value""10AIkMpJKJfC8vXacMI1Sg=="
    }
  ]}'''
def encryptionKeyId  = '176006'
def encryptionKeyB64 = 'KgUmyup/vxaFIi72PTDjWRxBFELfCaBc1fxYZb/vQNk='
print new TGClient().generateToken(contentKeyTokens_keys,
encryptionKeyB64, encryptionKeyId)

4.1.2.2. Result

> groovy -cp tg.jar scripts\kc.groovy
[INFO] 2016-10-11 15:33:49,444 - com.nagra.tg.client.TGClient.generateToken - 200:Success
[INFO] 2016-10-11 15:33:49,450 - com.nagra.tg.client.TGClient.generateToken - Token Written Successfully
[INFO] 2016-10-11 15:33:49,450 - com.nagra.tg.client.TGClient.generateToken - END: NagraTokenGen stops.
eyJrY0lkcyI6WyJmZmZmZmZmZi1hYWFhLWJiYmItY2NjYy0wMDAwMDAwMDA1MDEiLCJmZmZmZmZmZi1hYWFhLWJiYmItY2NjYy0wMDAwMDA
wMDA1MDIiXSwidHlwIjoiSldUIiwiZW5jIjoiQTEyOENCQy1IUzI1NiIsImFsZyI6ImRpciIsImtpZCI6IjE3NjAwNiJ9..xUYMm3Wpr6C_
aQFjffGoug.ZV_hXrv7LBJbCD2zfu-SB7iXtCsZKa_9vWvFgO-4tgm6kRtvlSg7vIcFVloZeKapIa_gT9i6RY2jM9rGuZBAJ2flYbVRQfv1j
jVex_PkWNnzs3GkgFcjqm23OlJ9PYZRQapaxItP3rWL88AuxwQTbeIC6vkbpKCEf1iw0EIZSemzUCXaoYacgCSHqL_0u3OWHrhknJhCHfQZi
HXC7UsZtprnFbvSS0lKCKQYqsuOTmz5duznKY4Jvl5Ae1uL5sENQsZ_ODOrVrASZAMzuYGp8w.QNU5ctHfpROhx3wtCIjykw

4.2. Troubleshooting

There are different error codes from different failure scenarios and written in log file under /logs directory. Refer to the following table of error codes to troubleshoot:


Error Code

Description Message

200

Token generated successfully

1001

Invalid signing key path

1002

Invalid encryption key path

1003

Configuration is missing

1004

Algorithm not supported, use HS256