---
title: "Token Protection: HMAC signature"
slug: "token-protection-hmac-signature"
updated: 2026-02-27T12:33:35Z
published: 2026-02-27T12:33:35Z
canonical: "help.movingimage.com/token-protection-hmac-signature"
---

> ## Documentation Index
> Fetch the complete documentation index at: https://help.movingimage.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Token Protection: HMAC signature

## **Protect Videos with Token Authentication**

### **Description**

Token authentication is a [security mechanism](/v1/docs/security-policy) that can be used to protect videos. It works by adding a token parameter to the HTML embed code for the video.

The token parameter is a hash of the video ID, the expiry time, and a secret key.

When a user clicks on the embedded video, the browser will send the token parameter to the VideoManager server.

The VideoManager server will verify the token and, if it is valid, will allow the user to watch the video.

### Steps

To use token authentication, you need to:

1. Enable the "Token Protection" feature in the Security Policy of the video.
2. Get the video ID and the expiry time from the video's metadata.
3. Get the secret key from the VideoManager administrator.
4. Calculate the HMAC signature using the video ID, expiry time, and secret key.
5. Add the token parameter to the HTML embed code, with the value of the HMAC signature.

Here is an example of an HTML embed code with the token parameter:

```plainText
<div mi24-video-player
         style=""
         config-type="vmpro" flash-path="https://e.video-cdn.net/v2"
         player-id="FDY_hXG2zDg8YjSjWe4GNT" video-id="4JsxZuu4Yc8L5C_dqejJne"
         api-url="//d.video-cdn.net/play"
         token="1461246419962~55e8fd678f425f67ae9689896020dcbf7718bbac2d799134b9d946392643a1cc">
</div>
<script type="text/javascript" src="https://e.video-cdn.net/v2/embed.js"></script>
```

In this example, the token parameter has the value `1461246419962~55e8fd678f425f67ae9689896020dcbf7718bbac2d799134b9d946392643a1cc`. This value is the HMAC signature calculated using the video ID `4JsxZuu4Yc8L5C_dqejJne`, the expiry time `1461246419962`, and the secret key.

### Calculate the HMAC signature

1. Create a message that includes the video ID and the expiry time.
2. Get the secret key from the VideoManager administrator.
3. Use the HMAC-SHA256 algorithm to calculate the signature of the message and the secret key.

#### **Required Authentication Information**

The following JSON object is used as the basis for calculating the signature:

```plainText
{
  "video-id": "%videoId%",
  "exp-time": "%expiryTime%"
}
```

- `video-id`: ID of the video
- `exp-time`: Time at which the signature is expired (epoch timestamp)

**Shared Secret**

The shared secret is a key that is used to generate the signature. The key can be retrieved in the security settings in your VideoManager (see [VideoManager Manual: Security Policy Configuration](/v1/docs/security-policy)).

### **Code Samples for Signature Generation**

The following code samples show how to calculate a HMAC signature using the shared secret and expiration time. The samples also demonstrate how to convert the token lifetime value from minutes to seconds and add it to the current epoch timestamp.

#### **Java Example**

```plainText
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.math.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
 
public class VMProToken {
 
    public static void main(String[] args) {
        final String videoID = "212zpS6bjN77eixPUMUEjR";
        final String sharedSecret = "abc123";
        final Duration lifeTime = Duration.of(5, ChronoUnit.MINUTES); //token expires in 5 minutes
         
        try {
            final String token = generateToken(videoID, sharedSecret, lifeTime);
            System.out.println(token);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            e.printStackTrace();
        }
    }
  
    private static String generateToken(String videoId, String sharedSecret, Duration lifeTime)
            throws NoSuchAlgorithmException, InvalidKeyException {
        final String HASH_PATTERN = "{\"video-id\":\"%s\", \"exp-time\": %s}";
        final String HASH_ALGORITHM = "HmacSHA256";
 
        final long expiryTime = Instant.now().plus(lifeTime).getEpochSecond();
 
        final String tokenCalcBase = String.format(HASH_PATTERN, videoId, expiryTime);
        final Mac hmac = Mac.getInstance(HASH_ALGORITHM);
        final byte[] keyBytes = DatatypeConverter.parseHexBinary(sharedSecret);
        final SecretKeySpec secretKey = new SecretKeySpec(keyBytes, HASH_ALGORITHM);
        hmac.init(secretKey);
        final byte[] hmacBytes = hmac.doFinal(tokenCalcBase.getBytes());
        final String hash = String.format("%064x", new BigInteger(1, hmacBytes));
 
        return expiryTime + "~" + hash;
    }
}
```

#### **Ruby Example**

```plainText
require 'openssl'
require 'date'

videoId = "212zpS6bjN77eixPUMUEjR"
sharedSecret = ["abc123"].pack('H*') #Hex2Bin
lifeTime = 5

expiryTime = (Time.now.to_i + (lifeTime*60)).to_s

message = sprintf("{\"video-id\":\"%s\", \"exp-time\": %s}", videoId, expiryTime)
hmac = OpenSSL::HMAC.hexdigest('sha256', sharedSecret , message)
token = expiryTime + "~" + hmac

printf("\nToken: %s\n", token)
```

#### **PHP Example**

```plainText
<?php
 
$videoId = "212zpS6bjN77eixPUMUEjR";
$sharedSecret = "abc123";
$lifeTime = 5;
 
function generateToken($videoId, $sharedSecret, $lifeTime)
{
  $expiryTime = time() + ($lifeTime*60);
  $data = sprintf("{\"video-id\":\"%s\", \"exp-time\": %s}" , $videoId, $expiryTime);
  $hash = hash_hmac ( "sha256", $data , hex2bin($sharedSecret) );
  $token = sprintf ("%s~%s", $expiryTime , $hash);
  return $token;
}
  
$token = generateToken($videoId, $sharedSecret, $lifeTime);
echo $token;
?>
```

### **Testing Your HMAC Implementation**

#### **Converting Lifetime to Expiry Time**

The code samples convert the token's "lifeTime" (in minutes) to "expiryTime" (the Unix epoch timestamp representing the exact second the token will expire). This means the generated code will be unique each time you calculate it, even if you input the same values. To avoid this, you can test your output using a specific expiryTime instead of calculating it.

#### **Testing Parameters**

Use the following parameters to test your HMAC implementation:

- videoId: 212zpS6bjN77eixPUMUEjR
- sharedSecret: abc123
- expiryTime: 1458396066

#### **Expected Signature**

The following signature should be calculated using these parameters:

```plainText
1458396066~62dcbe0e20827245454280c51129a9f30d1122eaeafc5ce88f0fec527631f1b5
```

### **Retrieve Token-Protected Videos**

To retrieve a token-protected video, you need to add the "token" parameter with the calculated signature to the "mi24-video-player" div tag of the desired video's HTML embed code.

**Important Notes:**

- The "token" parameter can only be added to the "mi24-video-player" div tag, meaning you must use the HTML embed code to publish a token-protected video.
- The embed code provided is for the movingimage video platform's general live instance. Embed codes for customers using a VideoManager on a custom domain will have different URLs.

**Example:**

```plainText
<div mi24-video-player
    style=""
    config-type="vmpro"
    flash-path="https://e.video-cdn.net/v2"
    player-id="FDY_hXG2zDg8YjSjWe4GNT"
    video-id="4JsxZuu4Yc8L5C_dqejJne"
    api-url="//d.video-cdn.net/play"
    token="1461246419962~55e8fd678f425f67ae9689896020dcbf7718bbac2d799134b9d946392643a1cc">
</div>

<script type="text/javascript" src="https://e.video-cdn.net/v2/embed.js"></script>
```

> [!NOTE]
> Using the new mi-player?
> 
> The token must now be appended to the iframe URL. See the Sharing and Embedding section in the [**mi-player FAQs**](https://help.movingimage.com/docs/player-faqs) for the updated implementation.
