Tính năng bảo mật liên kết

Giới thiệu

Secure link (bảo mật liên kết) là tính năng giúp bảo vệ các liên kết khỏi các truy cập không mong muốn. Tính năng này đảm bảo một liên kết chỉ có thể truy cập trong một khoảng thời gian xác định.

Cơ chế tạo liên kết bảo mật:

Ví dụ link gốc là: http://demo.cdn.vccloud.vn/video.mp4

Link secure sẽ có thêm 2 tham số e (expires) và s (signature) được tạo động theo từng url. Các liên kết có các tham số e & s hợp lệ sẽ trả ra bình thường, còn không hợp lệ sẽ báo lỗi 403:

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

Tham số e được tạo ra như sau:

e (expires) = unix timestamp hiện tại + số giây muốn expires

Ví dụ: unix timestamp hiện tại là 1444882020 (tương ứng với 11:07:00 ngày 15/10/2015); muốn link expires sau 900 giây (15 phút) thì lấy 1444882020 + 900 ra 1444882920 như vậy e = 1444882920

Tham số s (signature) là HMAC SHA1 của secret key + e + uri, đổi ra digest (không phải hexdigest), và convert sang urlsafe_b64encode; e là giá trị ở trên; uri là string lấy trên url, tính từ ký tự / sau domain.

Signature dùng urlsafe_b64encode, nghĩa là sau khi b64encode thường, sẽ làm thêm:

  • thay ký tự + thành –
  • thay ký tự / thành _
  • giữ nguyên ký tự =

Ví dụ

Code ví dụ bằng 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())

Code ví dụ bằng 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);
    }
}