Secure Link feature

Introduction

Secure link (also known as link security) is a feature that helps protect links from unwanted access. This feature ensures that a link can only be accessed within a specific time period.

For example, the original link is: http://demo.cdn.vccloud.vn/video.mp4

The secure link will have two additional parameters, e (expires) and s (signature), which are dynamically generated for each URL. Links with valid e and s parameters will return normally, while invalid ones will report a 403 error:

http://demo.cdn.vccloud.vn/video.mp4?e=1444987483&s=78lmi—L6kp-I2cJlpQrfOCRTUo==

The e parameter is generated as follows:

e (expires) = current unix timestamp + number of seconds until expiration

Example: current unix timestamp is 1444882020 (corresponding to 11:07:00 ngày 15/10/2015); If you want the link to expire after 900 seconds (15 minutes), then take 1444882020 + 900 equal 1444882920 then e = 1444882920

The s (signature) parameter is the HMAC SHA1 of the secret key + e + URI, converted to a digest (not hexdigest), and then converted to urlsafe_b64encode; e is the value from above; and uri is the string taken from the URL, starting from the character / after the domain.

Signature use urlsafe_b64encode, that means after the regular base64 encoding, you will additionally do the following:

  • replace the ‘+’ character with ‘-’
  • replace the / character with _
  • keep the ‘=’ character

Example

Here’s an example code in Python:

import time
import base64
import hmac
import hashlib

secret_key = "afb3e97623d84527957de13273f1c4f5"
uri = "/video.mp4"
expires = int(time.time()) + 900
text = str(expires) + '|' + uri
signature = hmac.new(secret_key.encode(), text.encode(), hashlib.sha1).digest()
signature = base64.urlsafe_b64encode(signature)

print(expires)
print(signature.decode())

Here’s an example code in Java:

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class Main
{
    static String secret_key = "afb3e97623d84527957de13273f1c4f5";
    static String uri = "/video.mp4";

    public static void main(String[] args) throws Exception {

        Long unixTime = System.currentTimeMillis() / 1000L;
        int expires = unixTime.intValue() + 900;
        String text = String.valueOf(expires) + '|' + uri;

        SecretKeySpec secretKeySpec = new SecretKeySpec(secret_key.getBytes(), "HmacSHA1");
        Mac mac = Mac.getInstance("HmacSHA1");
        mac.init(secretKeySpec);

        String signature = Base64.getUrlEncoder().encodeToString(mac.doFinal(text.getBytes()));
        System.out.println(expires);
        System.out.println(signature);
    }
}