Updated on 2025-07-25 GMT+08:00

URL Validation

To prevent livestream resources from being stolen, you can configure URL validation to add authentication information to the end of the original ingest or streaming URL. When a livestream is pushed or a viewer requests playback, CDN verifies the encrypted information in the URL. Only verified requests can be approved, and other illegitimate requests are rejected.

If you have other requirements on custom validation rules, submit a service ticket for Huawei Cloud technical support.

Working Principle

Figure 1 URL validation working principles

The process is as follows:

  1. A tenant enables URL validation on the Live console and configures the signing method, key, and duration.
  2. The configured signing method, key, and duration will be sent to a CDN PoP.
  3. The streamer or viewer requests CDN to push streams or play video through the signed ingest or streaming URL.
  4. CDN verifies the request based on authentication information in the URL. Only verified requests can be handled.

Notes

  • By default, URL validation is not displayed. To use it, submit a service ticket to apply for the permission.
  • This function is optional and is disabled by default. After this function is enabled, the original URLs cannot be used. New signed URLs must be generated following rules.
  • URL validation for streaming domain names supports only signing method D, which supports only HLS and does not support DASH or MSS.
  • If the stream push protocol of an ingest domain name is SRT, the configuration page of URL validation and ACL will be invisible. If you want to enable URL validation for an SRT ingest domain name, you can configure CIDR IP Whitelist and Primary Input Decryption Parameters (with Decryption enabled) when creating a channel. For details, see Creating a Channel.
  • Use different keys for stream push authentication and playback authentication to enhance security. If a signed URL expires or the signature fails the authentication, the livestream playback will fail and the message 403 Forbidden will be returned.
  • For persistent connection services such as RTMP and FLV, the server verifies the validation parameters only when receiving a user request. Once verified, the content can be played continuously.
  • For HLS services, users keep sending requests that contain the same validation parameters after content is played. Once the validation parameters expire, the server rejects the access request because the verification fails, which will interrupt the playback.

    For such services, you need to set a proper authentication expiration time to prevent playback failures. For example, if the estimated HLS playback lasts less than 1 hour each time, you can set the expiration time to 3,600 seconds.

Enabling URL Validation

  1. Log in to the Live console.
  2. In the navigation pane, choose Domains.
  3. Click Manage in the Operation column of the desired domain name.
  4. In the navigation pane, choose Basic Settings > Access Control.
  5. Click Edit on the right of URL Validation. The URL Validation dialog box is displayed.
  6. Toggle on the Status switch to configure related parameters, as shown in Figure 2.

    An ingest domain name supports four signing methods (A, B, C, and D), while a streaming domain name supports only signing method D. The following figure uses an ingest domain name as an example.
    Figure 2 Configuring URL validation
    Table 1 URL validation parameters

    Parameter

    Description

    Type

    You can use signing method A, B, C, or D to calculate a signed string.

    Signing methods A and B: The Message Digest algorithm 5 (MD5) is used. For details, see Signing Method A and Signing Method B.

    Signing method C: A symmetric encryption algorithm is used. For details, see Signing Method C.

    Signing method D: The HMAC-SHA256 algorithm is used. For details, see Signing Method D.

    NOTE:
    • Signing methods A, B, and C have security risks. Signing method D is more secure and recommended.
    • URL validation for streaming domain names supports only signing method D, which supports only HLS and does not support DASH or MSS.

    Key

    Authentication key.

    • You can customize a key, which consists of 32 characters in letters and digits.
    • A key can also be automatically generated.

    Duration

    Timeout interval of URL authentication information, that is, the maximum difference between the request time carried in authentication information and the time when Live receives the request. This parameter is used to check whether an ingest URL or streaming URL expires. The unit is second. The value ranges from 1 minute to 30 days.

    NOTE:
    • For persistent connection services such as RTMP and FLV, the server verifies the validation parameters only when receiving a user request. Once verified, the content can be played continuously.
    • For HLS services, users keep sending requests that contain the same validation parameters after content is played. Once the validation parameters expire, the server rejects the access request because the verification fails, which will interrupt the playback.

      For such services, you need to set a proper authentication expiration time to prevent playback failures. For example, if the estimated HLS playback lasts less than 1 hour each time, you can set the expiration time to 3,600 seconds.

  7. Click OK.
  8. Obtain a signed URL in either of the following ways:

  9. Verify whether URL validation has taken effect.

    Use a third-party livestreaming tool to verify the signed ingest URL and streaming URL. If the original ingest URL and streaming URL cannot be used but the signed ingest URL and streaming URL can, URL validation has taken effect.

Signing Method A

  • Signing method A is supported only by RTMP ingest domain names, but not by streaming domain names.
  • Use the validation address generation tool to quickly generate a signed URL for an RTMP ingest domain name. This method is recommended. For details, see Signed URL Generation Tool.

A signed string is calculated based on the Key, timestamp, rand (random), uid (set to 0), and URL.

Signed URL format:
Original URL?auth_key={timestamp}-{rand}-{uid}-{md5hash}
Formula for calculating md5hash is:
sstring = "{URI}-{Timestamp}-{rand}-{uid}-{Key}"
HashValue = md5sum(sstring)
Table 2 Authentication fields

Field

Description

timestamp

Start time of a valid request. The value is the total number of seconds that have elapsed since 00:00:00 January 1, 1970. It is a decimal or hexadecimal integer.

Example: 1592639100 (June 20, 2020 15:45)

Duration

How long a signed URL remains effective.

If the validity period is set to 1,800s, users can access the streaming URL within 1,800s since the time indicated by timestamp. Authentication fails and the URL is inaccessible if users access the streaming URL 1800s later.

For example, if the access time is 00:00:00 (GMT+08:00) on June 30, 2020, the URL expires at 00:30:00 (GMT+08:00) on June 30, 2020.

rand

Random number. The recommended value is a UUID, which cannot contain hyphens (-).

Example: 477b3bbc253f467b8def6711128c7bec

uid

User ID. This parameter is not used now. Set it to 0.

md5hash

A string of 32 characters calculated using the MD5 algorithm. The string consists of digits (0 to 9) and lowercase letters.

sstring = "{URI}-{Timestamp}-{rand}-{uid}-{Key}"
HashValue = md5sum(sstring)

URI

The original URL part that starts on the right of the domain name to the left of the question mark (?). For example, if the original URL is rtmp://live-push.example.com/live/huaweitest?request_source=ott&channel_id=huaweitest, the URI is /live/huaweitest.

Key

Key value set on the console. For details, see Enabling URL Validation.

Signed URL example:

The following shows how to generate a signed ingest URL:
Original URL: rtmp://live-push.example.com/live/huaweitest?request_source=ott&channel_id=huaweitest
timestamp: 1592639100
Duration: 1800s
Key: GCTbw44s6MPLh4GqgDpnfuFHgy25Enly
rand: 477b3bbc253f467b8def6711128c7bec
uid: 0
URI: /live/huaweitest
Obtain md5hash using the calculation formula.
HashValue = md5sum("/live/huaweitest-1592639100-477b3bbc253f467b8def6711128c7bec-0-GCTbw44s6MPLh4GqgDpnfuFHgy25Enly") = 1832e24276a08e180152c9c8a98ff322

The signed ingest URL is:

rtmp://live-push.example.com/live/huaweitest?request_source=ott&channel_id=huaweitest&auth_key=1592639100-477b3bbc253f467b8def6711128c7bec-0-1832e24276a08e180152c9c8a98ff322

Signing Method B

  • Signing method B is supported only by RTMP ingest domain names, but not by streaming domain names.
  • Use the validation address generation tool to quickly generate a signed URL for an RTMP ingest domain name. This method is recommended. For details, see Signed URL Generation Tool.

A signed string is calculated based on the Key, timestamp, and StreamName.

Signed URL format:
Original URL?txSecret=md5(Key + StreamName + txTime)&txTime=hex(timestamp)
Table 3 Authentication fields

Field

Description

txTime

Effective time of a streaming URL. The value is a hexadecimal Unix timestamp.

If the value of txTime is greater than the requested time, the playback is normal. Otherwise, the playback is rejected.

Example: 5eed5888 (that is, 2020.06.20 08:30:00)

Key

Key value set on the console. For details, see Enabling URL Validation.

txSecret

Encryption parameter in the URL.

The value is obtained by using the MD5 encryption algorithm to encrypt the string consisting of key, StreamName, and txTime.

txSecret = md5 (Key + StreamName + txTime)

Duration

How long a signed URL remains effective.

If txTime is set to the current time and the validity period is set to 1,249s, the streaming URL expiration time is the current time plus 1,249s.

Signed URL example:

The following shows how to generate a signed ingest URL:
Original URL: rtmp://live-push.example.com/live/huaweitest?request_source=ott&channel_id=huaweitest
Key: GCTbw44s6MPLh4GqgDpnfuFHgy25Enly
StreamName: huaweitest
txTime: 5eed5888
Duration: 1,249s
Obtain txSecret based on the calculation formula.
txSecret = md5(GCTbw44s6MPLh4GqgDpnfuFHgy25Enlyhuaweitest5eed5888) = 1f5b30ca84581f14efd1f7aa39def2e3

The signed ingest URL is:

rtmp://live-push.example.com/live/huaweitest?request_source=ott&channel_id=huaweitest&txSecret=1f5b30ca84581f14efd1f7aa39def2e3&txTime=5eed5888

Signing Method C

  • Signing method C is supported only by RTMP ingest domain names, but not by streaming domain names.
  • Use the validation address generation tool to quickly generate a signed URL for an RTMP ingest domain name. This method is recommended. For details, see Signed URL Generation Tool.

A signed string is calculated based on the Key, Timestamp, AppName, StreamName, and CheckLevel.

Signed URL format:
Original URL?auth_info={Encrypted string}.{EncodedIV}
The algorithm for generating the authentication fields is as follows. For details about the code example, see Sample Code.
  • LiveID = <AppName>+"/"+<StreamName>
  • Encrypted string = UrlEncode(Base64(AES128(<Key>,"$"+<Timestamp>+"$"+<LiveID>+"$"+<CheckLevel>)))
  • EncodedIV = Hex (IV used for encryption)

Table 4 describes encryption parameters in the algorithm.

Table 4 Encryption parameters

Field

Description

AppName

Application name, which is the same as the value of AppName in an ingest or streaming URL

StreamName

Stream name, which is the same as the value of StreamName in an ingest or streaming URL

Key

Key value set on the console. For details, see Enabling URL Validation.

LiveID

Livestream ID, which uniquely identifies a livestream. The value consists of AppName and StreamName.

LiveID = <AppName>+"/"+<StreamName>

Timestamp

UTC time when an authentication parameter is generated, in yyyyMMddHHmmss format. This parameter is used to check whether the authentication parameter has expired, that is, whether the absolute value of the difference between Timestamp and the current time is greater than the configured timeout interval.

CheckLevel

Check level. The value is 3 or 5.

  • If CheckLevel is 3, the system only checks whether the value of LiveID is matched.
  • If CheckLevel is 5, the system checks whether the value of LiveID is matched and whether Timestamp times out.

IV

Cipher block chaining (CBC) depends on the initialization vector (IV). IV consists of 16 random digits and letters and must be 128 bits. In CBC mode, PKCS7 padding is used.

Signed URL example:

The following shows how to generate a signed ingest URL:

Original URL: rtmp://live-push.example.com/live/huaweitest?request_source=ott&channel_id=huaweitest
AppName: live
StreamName: huaweitest
Key: GCTbw44s6MPLh4GqgDpnfuFHgy25Enly
LiveID: live/huaweitest
Timestamp: 20190428110000
CheckLevel: 3
IV: yCmE666N3YAq30SN
The encrypted string and EncodedIV are obtained according to the calculation formula.
Encrypted string = I90KW7GhxOMwoy5yaeKMSk%2FsLt08T4Wlc6avfPBz9FQGlHRFOgkTOGHXWsXfL44x.
EncodIV = 79436d453636364e335941713330534e
The signed ingest URL is:
rtmp://live-push.example.com/live/huaweitest?request_source=ott&channel_id=huaweitest&auth_info=I90KW7GhxOMwoy5yaeKMSk%2FsLt08T4Wlc6avfPBz9FQGlHRFOgkTOGHXWsXfL44x.79436d453636364e335941713330534e

Signing Method D

  • Signing method D is supported only by RTMP ingest domain names and HLS streaming domain names.
  • Use the validation address generation tool to quickly generate a signed URL for an RTMP ingest domain name. This method is recommended. For details, see Signed URL Generation Tool.

A signed string is calculated based on the Key, timestamp, and StreamName.

Signed URL format:
Original URL?hwSecret=hmac_sha256(Key, StreamName + hwTime)&hwTime=hex(timestamp)
Table 5 Authentication fields

Field

Description

hwTime

Effective time of a streaming URL. The value is a hexadecimal Unix timestamp.

If the value of hwTime + duration is greater than the requested time, the playback is normal. Otherwise, the playback is rejected.

Example: 5eed5888 (that is, 2020.06.20 08:30:00)

Key

Key value set on the console. For details, see Enabling URL Validation.

hwSecret

Encryption parameter in the URL.

The value is obtained using the HMAC-SHA256 algorithm, with Key and StreamName + hwTime as parameters.

hwSecret = hmac_sha256 (Key, StreamName + hwTime)

Duration

How long a signed URL remains effective.

If hwTime is set to the current time and the validity period is set to 1,249s, the streaming URL expiration time is the current time plus 1,249s.

Signed URL example:

Generating a signed streaming URL is used as an example.
Original URL: https://live-play.example.com/{channelld}/hls/{unique_string}/index.m3u8
Key: GCTbw44s6MPLh4GqgDpnfuFHgy25Enly
StreamName: index
hwTime: 5eed5888
Duration: 1,249s
Obtain hwSecret based on the calculation formula.
hwSecret = hmac_sha256(GCTbw44s6MPLh4GqgDpnfuFHgy25Enly, index5eed5888) = 63eb41e0c5c8d8f8058aa83488901ad279645217f7099a2bcdef4f0044aa5b4f

The signed streaming URL is:

https://live-play.example.com/{channelld}/hls/{unique_string}/index.m3u8?hwSecret=63eb41e0c5c8d8f8058aa83488901ad279645217f7099a2bcdef4f0044aa5b4f&hwTime=5eed5888

Sample Code

The following is the code example for generating a signed string in method C:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

public class Main {

        public static void main(String[] args) {

		// data="$"+<Timestamp>+"$"+<LiveID>+"$"+<CheckLevel>. For details, see "Signing Method C."
                String data = "$20190428110000$live/stream01$3";

                // A random 16-digit string consisting of digits and letters
		byte[] ivBytes = "yCmE666N3YAq30SN".getBytes();

                // Key value configured on the Live console
		byte[] key = "GCTbw44s6MPLh4GqgDpnfuFHgy25Enly".getBytes();

                String msg = aesCbcEncrypt(data, ivBytes, key);
		try {
			System.out.println(URLEncoder.encode(msg, "UTF-8") + "." + bytesToHexString(ivBytes));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
	}

        private static String aesCbcEncrypt(String data, byte[] ivBytes, byte[] key) {
		try {
			SecretKeySpec sk = new SecretKeySpec(key, "AES");
			Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

                        if (ivBytes != null) {
				cipher.init(Cipher.ENCRYPT_MODE, sk, new IvParameterSpec(ivBytes));
			} else {
				cipher.init(Cipher.ENCRYPT_MODE, sk);
			}

                        return Base64.encode(cipher.doFinal(data.getBytes("UTF-8")));
		} catch (Exception e) {
			return null;
		}
	}

        public static String bytesToHexString(byte[] src) {
		StringBuilder stringBuilder = new StringBuilder("");
		if ((src == null) || (src.length <= 0)) {
			return null;
		}

                for (int i = 0; i < src.length; i++) {
			int v = src[i] & 0xFF;
			String hv = Integer.toHexString(v);
			if (hv.length() < 2) {
				stringBuilder.append(0);
			}
			stringBuilder.append(hv);
		}
		return stringBuilder.toString();
	}
}

Base64 is used to encode encrypted strings.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class Base64
{

    / ** Base64 encoding table */
    private static char base64Code[] =
    {
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
        'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
        'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1',
        '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',};

    /**
     * The construction method is privatized to prevent instantiation.
     */
    private Base64()
    {
        super();
    }

    /**
     * Encode three bytes in a byte array into four visible characters.
     * @param bytes Byte data to be encoded
     * @return Base64 character string after encoding
     */
    public static String encode(byte[] bytes)
    {
        int a = 0;

        // Allocate memory based on the actual length after encoding for acceleration.
        StringBuffer buffer = new StringBuffer(((bytes.length - 1) / 3) << 2 + 4);

        // Encoding
        for (int i = 0; i < bytes.length; i++)
        {
            a |= (bytes[i] << (16 - i % 3 * 8)) & (0xff << (16 - i % 3 * 8));
            if (i % 3 == 2 || i == bytes.length - 1)
            {
                buffer.append(Base64.base64Code[(a & 0xfc0000) >>> 18]);
                buffer.append(Base64.base64Code[(a & 0x3f000) >>> 12]);
                buffer.append(Base64.base64Code[(a & 0xfc0) >>> 6]);
                buffer.append(Base64.base64Code[a & 0x3f]);
                a = 0;
            }
        }

        // For a byte array whose length is not an integral multiple of 3, add 0 before encoding and replace it with = after encoding.
        // The number of equal signs (=) is the same as the length of the missing data to identify the actual data length.
        if (bytes.length % 3 > 0)
        {
            buffer.setCharAt(buffer.length() - 1, '=');
        }
        if (bytes.length % 3 == 1)
        {
            buffer.setCharAt(buffer.length() - 2, '=');
        }
        return buffer.toString();
    }

}