Token Integration

1. Summary

The purpose of this document is to outline the work required to integrate the vudrm token solution into the client’s DRM workflow. This document replaces previous versions and instead of providing integration instructions for each individual DRM provider, now allows a common set of parameters to be used across multiple DRM platforms. This new common layer supports the following DRM technologies:

• Adobe Primetime (formerly Access)

• Microsoft PlayReady

• Google Widevine Modular

There are some settings that do now apply to every DRM. These have been indicated.

2. Token Overview

In order to authenticate a request for playback, a system of signed tokens is used.

• The signed token includes all the policy information and the playback rules for the content.

• These tokens are usually created by the client CMS and are passed to the player along with the URL of the content. This means that DRM policies can be created on-the-fly and can change according to the playback/user scenario. This methods avoids having to ‘burn in’ the policy information into the content and avoids having to re-encypt the content.

• When playback of the content is requested, the player sends the token to the appropriate DRM Licence Server.

• The signed token identifies and authenticates the player to Vualto, and specifies what licence parameters should be set in the new licence.

• This token represents a signed authorisation on the client’s behalf for Vualto to issue a license to the holder of the token, so issuing a token to a player will grant that player access to the DRM-protected content. The lifetime of a token is specified in the client account settings but the default is 60 seconds. If the token is not used by the player within the lifetime then the token expires and will no longer be accepted by the license server.

(For Adobe Primetime only, we also support ‘pre-defined’ DRM policies files.)

2.1 Token Format for On-the-fly Policies

The Signed tokens contain:

• The client Account name

• Creation timestamp (Format ISO8601 yyyy-MM-ddThh:mm:ssZ)

• JSON parameters appropriate to DRM Policy requirements (Encrypted)

• Signed hash

Example Encrypted Token:

TestClientX|2014-0906T14:33:04Z|cO9H1B2VKw0WyyNTOfoHEw==|05aff2dd06f4c52291b7a032c815ce8f599cf409

Each component is separated with a vertical bar character (ASCII code 124).
The JSON is encrypted using AES (rijndael 128) so should anyone intercept the request the DRM policy token information is secure.

2.2 Token Format for Pre-Defined Policy (Primetime Only)

If the policy is to be ‘burnt’ into the content, then instead of specifying the Policy JSON, a policy name is specified.

The signed token contains:

• The client Account name

• Creation timestamp (Format ISO8601 yyyy-MM-ddThh:mm:ssZ)

• Policy Name (eg. 30 days, DTO)

• Signed hash

Example Encrypted Token

TestClient|2012-03-09T11:27:57Z|30 Day|e03a31b675a5191235dc49c83ddbfe06cf66f44a

Each component is separated with a vertical bar character (ASCII code 124).
The JSON is encrypted using AES (rijndael 128) so should any one intercept the request the DRM policy token information is secure.

2.3 JSON Parameters for DRM Policies

The following parameters are the most commonly used to specify DRM policies. It is not an exhaustive list but covers off most common scenarios.

For those clients using multiple DRM providers, the Parameters that are applicable to All will work across DRM technologies. Parameters specific to one DRM can be used but will be ignored if not relevant. For example, a token can be created that pertains to both Widevine and PlayReady. Any PlayReady specific parameters from the list below will only be applied when a PlayReady licence is required and will be ignored for Widevine.

Context Parameter Name Parameter Contents/Format Description Appicable DRM
contentid name of the file An identifier of the content ALL
Policy Duration polbegin dd-mm-yyyy hh:mm:ss The policy Start date ALL
polend dd-mm-yyyy hh:mm:ss The policy Expiration date ALL
Licence Caching licdelete dd-mm-yyyy hh:mm:ss Date licence is removed from local device if it still exists ALL
liccache yes/no Whether licence is cached (persistent) or not cached (nonpersistent) on local device ALL
lic.cache.after Integer (seconds) Delete licence after number of 6 seconds Primetime
Playback Window firstplayback Integer (seconds) Time from the first playback to licence expiry. Used in rental situations ALL
Output Protection out.analog [noprot = no protection, req = required, use = use if available, noplay = no playback] req/use/noplay Primetime
out.digital [noprot = no protection, req = required, use = use if available, noplay = no playback] req/use/noplay Primetime
** right.AnalogVideoOPLl Integer value eg. 200 Minimum Analog Video Output Protection Level PlayReady
** right.UncompressedDigitalAudioOPL Integer value eg. 200 Minimum Uncompressed Digital Audio Output Protection Level PlayReady
** right.UncompressedDigitalVideoOPL Integer value eg. 200 Minimum Uncompressed Digital Video Output Protection Level PlayReady
** right.CompressedDigitalVideoOPL Integer value eg. 200 Minimum Compressed Digital Video Output Protection Level PlayReady
track_type String Track type name such as video/audio etc. Widevine
security_level Integer Client robustness requirements for playback: 1. The Software based whitebox crypto is required 2. Software crypto & obfuscated decoder is required 3. Key material and crypto ops must be performed within the hardware backed, trusted execution environment. 4. Crypto and decoding performed within hardware backed trusted execution environment. 5. The crypto, decoding and all handling of the media must be handled in a hardware backed trusted execution environment Widevine
required_output_protection.hdcp HDCP_NONE, HDCP_V1, HDCP_V2 Indicates whether HDCP is required. Widevine
key Base64 Content key to use for this track. If used, then the track_type or key_id is required. Widevine
key_id Base64 encoded string Unique identifier for the key Widevine
Other Common Parameters Securitylevel 150/2000 Refers to the robustness level of DRM SDK. 150 for non-commercial application (testing/development) 2000 for commercial application PlayReady
airplay Use "1" to enable Airplay PlayReady
lic.chain yes / no (default) Whether a root licence can unlockleaf licences Primetime
Fairplay Token Requirement type string "r" "r" for rental, "l" for lease, "b"string for both Fairplay
Fairplay Token Requirement duration_rental 3600 The period before a new FPS license request is needed Fairplay

** PlayReady output protection is complex and there are too many parameter values to list in this table.

For a full explanation of PlayReady output protection, please see:

https://www.microsoft.com/playready/licensing/compliance/

Simple JSON Examples

Example Rental : All DRM Providers:


    {
        "contentid":"filename",
        "polbegin":"DD-MM-YYYYHH:MM:SS",
        "licdelete":"DD-MM-YYYYHH:MM:SS",
        "liccache":"yes",
        "firstplayback":172800
    }

The policy needs to be timestamped with the correct date and time of when the rental period ends. This ensures that any request for a license outside the policy window will fail and that any cached license is also removed.

Each time a user requests playback it will check the local cache for a license. If it finds one it will play (if the license is valid) and if not it will request one from the server. As long as the client continues to timestamp the policy end date based on the initial purchase it will be valid for the correct period.

Example Download to Own : All DRM Providers:


    {
        "contentid":"filename",
        "polbegin":"DD-MM-YYYY HH:MM:SS",
        "liccache":"yes"
    }

Example Subscription : All DRM Providers:

    {
        "contentid":"filename",
        "polend":"DD-MM-YYYY HH:MM:SS",
        "liccache":"no"
    }

2.4 Encrypting the Token

The hash is the final component and it is created by computing the values within the token and a shared secret using the SHA1 hashing algorithm.

The shared secret is private between the client and Vualto and should not be disclosed, however if the shared secret is compromised then a new code can be issued and the old code will be revoked.

The encrypted token is made up of:

signedToken = accountName + verticalBar + timestamp + verticalBar + policy + verticalBar + computedHash

The Hash is made up of:

SHA1(sharedSecret + preComputedValues)

Where:

shared Secret = "gLhkdpugeeLBoVPTINhXfKlZKbxsiaAvediToniPlQKxj4pJRqyXQaTjpqiQleAwPupekqrYtliV0BnLdlz6jhUxLLoavtXzvZn4UutjoinLdMdprugtpoPniIzStgli"

And:

preComputed values = accountName + timestamp + policy

2.5 Using the Token API

We provide a secure API to generate a token for your content. This is accessed from the following URL:

https://token-api.drm.technology/generate

The request needs to be a post and requires the following:

• A Header called “API-KEY” this key is your api-key which is provided behind your login at admin.drm.technology

• A body comprising of your name and the policy (which is generated using the above guides).

The body contains a JSON object which will need to be escaped. For example:


    {
        "client": "YOUR_NAME",
        "policy": "{
                    \"contentid\":\"test\",
                    \"polend\":\"04-01-2016 16:48:59\",
                    \"liccache\":\"no\"
                   }"
    }   

2.5.1 Token API Request Example

The following API request example is written in PHP.


<?php%
    $apikey='YOUR_API_KEY';%
    $clientname="YOU_CLIENT_NAME";%
    $contentid="YOUR%CONTENT%ID";%
    $dateend=date('dHmHY%H:i:s',time()+7200);%
    $policy=json_encode(array('contentid'=>$contentid,'polend'=>$dateend,'liccache'=>'no'));%
    $data_json%=%json_encode(array("client"=>$clientname,"policy"=>$policy));%
    $ch%=%curl_init('https://token-api.drm.technology/generate');%
    curl_setopt($ch,%CURLOPT_HTTPHEADER,%array('APIHKEY:%$apikey'));%
    curl_setopt($ch,%CURLOPT_POST,%1);%
    curl_setopt($ch,%CURLOPT_SSL_VERIFYPEER,%false);%
    curl_setopt($ch,%CURLOPT_POSTFIELDS,$data_json);%
    curl_setopt($ch,%CURLOPT_RETURNTRANSFER,%1);%
    $response%=%curl_exec($ch);%
    echo%$response;%
?>%