全部产品
Search
文档中心

ApsaraVideo VOD:Enkripsi HLS

更新时间:Jan 30, 2026

Enkripsi HTTP Live Streaming (HLS) menggunakan algoritma AES-128. Metode ini kompatibel dengan semua pemutar HLS dan memanfaatkan layanan manajemen kunci serta token untuk kontrol akses. Enkripsi HLS banyak digunakan dalam skenario yang memerlukan keamanan tinggi, seperti pendidikan daring dan streaming konten eksklusif. Topik ini menjelaskan cara menggunakan enkripsi HLS untuk mengenkripsi video dan mendekripsinya saat diputar.

Cara kerja

ApsaraVideo VOD menggunakan enkripsi amplop. Layanan Anda memanfaatkan Alibaba Cloud Key Management Service (KMS) untuk menghasilkan kunci data (DK) dan kunci data teramplop (EDK). Setelah Anda menggunakan DK untuk mengenkripsi video, video terenkripsi dan EDK disimpan. Saat pemutaran, layanan dekripsi mengambil DK untuk mendekripsi video tersebut.

Untuk melakukan otentikasi keamanan pada alamat dekripsi, Anda dapat mengaktifkan Enkripsi dan penulisan ulang M3U8 guna menambahkan lapisan perlindungan tambahan pada proses akses data HLS. Parameter penulisan ulang default adalah MtsHlsUriToken. Untuk informasi selengkapnya tentang cara mengaktifkan Enkripsi dan penulisan ulang M3U8 serta cara kerjanya, lihat Konfigurasi Enkripsi dan penulisan ulang M3U8.

Prasyarat

  • Alibaba Cloud Video Encryption (enkripsi HLS) adalah layanan gratis. Namun, transkoding video diperlukan untuk menggunakan fitur ini. Operasi transkoding dikenai biaya layanan. Untuk informasi selengkapnya tentang penagihan, lihat Penagihan transkoding media.

  • ApsaraVideo VOD telah diaktifkan. Untuk informasi selengkapnya, lihat Mengaktifkan ApsaraVideo VOD.

  • Anda telah memberikan izin yang diperlukan kepada ApsaraVideo VOD untuk mengakses KMS. Anda dapat memberikan izin tersebut melalui halaman Otorisasi Akses Sumber Daya Cloud.

  • Nama domain yang dipercepat telah dikonfigurasi di ApsaraVideo VOD. Untuk informasi selengkapnya, lihat Tambahkan nama domain yang dipercepat.

  • Kit pengembangan perangkat lunak (SDK) sisi server ApsaraVideo VOD telah diinstal. Untuk informasi selengkapnya, lihat SDK sisi server. Topik ini menggunakan SDK untuk Java sebagai contoh.

Istilah

Konsep

Deskripsi

Resource Access Management (RAM)

Layanan Alibaba Cloud yang dapat Anda gunakan untuk mengelola identitas pengguna dan izin akses sumber daya. Untuk informasi selengkapnya, lihat Apa itu RAM?.

Key Management Service (KMS)

Platform terpadu untuk manajemen kunci dan enkripsi data. Layanan ini menyediakan kemampuan perlindungan enkripsi serta manajemen kredensial yang sederhana, andal, aman, dan sesuai regulasi. Untuk informasi selengkapnya, lihat Apa itu KMS?.

Data key (DK)

Kunci teks biasa yang digunakan untuk mengenkripsi data. Untuk informasi selengkapnya, lihat Istilah.

Enveloped data key (EDK)

Kunci data ciphertext yang dilindungi menggunakan enkripsi amplop. Untuk informasi selengkapnya, lihat Istilah.

Proses Enkripsi dan Dekripsi

Proses unggah dan enkripsi

视频安全-HLS标准加密3

Proses dekripsi dan pemutaran

Enkripsi dan penulisan ulang M3U8 diaktifkan (Direkomendasikan)

视频安全-HLS标准加密6..png

Enkripsi dan penulisan ulang M3U8 tidak diaktifkan

视频安全-HLS标准加密2

Enkripsi Video

  1. Unggah video dan terima callback.

    Untuk mencegah video yang dienkripsi HLS ditranskode secara otomatis, gunakan kelompok templat bawaan No Transcoding saat mengunggahnya ke ApsaraVideo VOD.

    1. Unggah video menggunakan konsol ApsaraVideo VOD atau dengan memanggil operasi API. Untuk informasi selengkapnya, lihat Unggah file media menggunakan konsol ApsaraVideo VOD dan Unggah media.

    2. Konfigurasikan notifikasi event untuk ApsaraVideo VOD. Saat Anda menerima pesan callback Video Upload Completed, berarti video telah berhasil diunggah ke ApsaraVideo VOD. Untuk informasi selengkapnya tentang cara mengonfigurasi notifikasi event, lihat Notifikasi event.

  2. Siapkan layanan enkripsi.

    1. Buat kunci layanan.

      Kunci layanan adalah kunci enkripsi utama di KMS dan diperlukan untuk menghasilkan kunci enkripsi standar. Jika Anda tidak membuat kunci layanan, akan muncul error saat memanggil operasi GenerateDataKey untuk menghasilkan kunci.

      1. Di pojok kiri atas halaman, klik ID wilayah untuk beralih ke wilayah tempat Anda ingin membuat kunci layanan.

        Catatan

        Kunci layanan harus berada di wilayah yang sama dengan server origin tempat video Anda disimpan. Misalnya, jika video Anda disimpan di Tiongkok (Shanghai), kunci layanan juga harus dibuat di Tiongkok (Shanghai).

        标准加密-服务地域

      2. Masuk ke konsol ApsaraVideo VOD. Di panel navigasi sebelah kiri, pilih Configuration Management > Media Processing > HLS Standard Encryption.

      3. Pada halaman Standard Encryption, klik Create Service Key.

        Setelah kunci layanan dibuat, pesan akan ditampilkan. Anda dapat melihat kunci layanan Anda di bagian Key Information.

        Catatan

        Jika muncul pesan bahwa kunci layanan telah dibuat tetapi Anda tidak dapat melihatnya, kemungkinan peran terkait layanan belum tersedia. Anda dapat memberikan kembali izin untuk memulihkan peran tersebut, lalu refresh halaman untuk melihat kunci layanan.

    2. Panggil operasi API untuk menghasilkan kunci data.

      Panggil operasi GenerateDataKey untuk menghasilkan DK dan EDK. Anda tidak perlu meneruskan parameter apa pun untuk operasi ini. Setelah panggilan berhasil, `CiphertextBlob` dalam tanggapan merupakan EDK dalam format AES-128. Anda harus menyimpan nilai ini untuk enkripsi standar dan transkoding. `Plaintext` dalam tanggapan merupakan DK.

  3. Buat grup template transcoding untuk enkripsi HLS.

    Proses enkripsi HLS memerlukan dua kelompok templat transkoding: kelompok templat bawaan No Transcoding dan kelompok templat transkoding enkripsi HLS kustom. Langkah-langkah berikut menjelaskan cara membuat kelompok kustom:

    1. Masuk ke konsol ApsaraVideo VOD. Di panel navigasi sebelah kiri, pilih Configuration Management > Media Processing > Transcoding Template Groups.

    2. Di halaman Kelompok Templat Transkoding, buat kelompok templat untuk enkripsi HLS.

      Atur Encapsulation Format menjadi hls. Di bagian Advanced Parameters, aktifkan Video Encryption dan pilih Alibaba Cloud Encryption. Anda dapat mengonfigurasi parameter lain sesuai kebutuhan. Untuk informasi selengkapnya, lihat Templat transkoding.视频安全-HLS加密-控制台

    3. Setelah templat dibuat, Anda dapat melihat ID kelompok templat transkoding di halaman Transcoding Template Groups. Simpan ID tersebut. Anda akan memerlukannya nanti saat memulai enkripsi dan transkoding HLS.视频安全-HLS加密-控制台1

  4. Memulai enkripsi dan transkoding HLS.

    1. Panggil operasi SubmitTranscodeJobs untuk memulai enkripsi dan transkoding HLS.

      Perluas untuk melihat kode contoh Java

      Parameter berikut dalam kode contoh Java harus diubah sesuai kebutuhan Anda:

      Parameter

      Nilai Input

      request.setTemplateGroupId("")

      ID kelompok templat transkoding untuk enkripsi HLS yang Anda buat di Langkah 3.

      request.setVideoId("")

      ID video yang akan dienkripsi yang Anda unggah di Langkah 1.

      encryptConfig.put("CipherText","")

      Nilai CiphertextBlob yang dikembalikan di Langkah 2.

      encryptConfig.put("DecryptKeyUri","")

      URI kunci. URI kunci merupakan kombinasi dari alamat layanan dekripsi dan nilai CiphertextBlob. Misalnya, jika port lokal adalah 8099, URI kuncinya adalah sebagai berikut:

      http://172.16.0.1:8099?CipherText=CiphertextBlobValue

      import com.alibaba.fastjson.JSON;
      import com.alibaba.fastjson.JSONObject;
      import com.aliyuncs.DefaultAcsClient;
      import com.aliyuncs.exceptions.ClientException;
      import com.aliyuncs.profile.DefaultProfile;
      import com.aliyuncs.vod.model.v20170321.SubmitTranscodeJobsRequest;
      import com.aliyuncs.vod.model.v20170321.SubmitTranscodeJobsResponse;
      
      public class SubmitTranscodeJobs {
      
          // Pasangan AccessKey akun Alibaba Cloud memiliki izin untuk memanggil semua operasi API. Kami menyarankan agar Anda menggunakan pasangan AccessKey pengguna RAM untuk memanggil operasi API atau melakukan O&M rutin.
          // Kami sangat menyarankan agar Anda tidak menyematkan ID AccessKey dan rahasia AccessKey secara langsung dalam kode proyek Anda. Jika tidak, pasangan AccessKey tersebut dapat bocor, sehingga mengancam keamanan semua sumber daya Anda.
          // Contoh ini menunjukkan cara membaca pasangan AccessKey dari variabel lingkungan untuk mengotentikasi akses API. Sebelum menjalankan kode, konfigurasikan variabel lingkungan ALIBABA_CLOUD_ACCESS_KEY_ID dan ALIBABA_CLOUD_ACCESS_KEY_SECRET.
          private static String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
          private static String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
      
          public static SubmitTranscodeJobsResponse submitTranscodeJobs(DefaultAcsClient client) throws Exception{
              SubmitTranscodeJobsRequest request = new SubmitTranscodeJobsRequest();
              request.setTemplateGroupId("");
              request.setVideoId("");
              JSONObject encryptConfig = new JSONObject();
              encryptConfig.put("CipherText","");
              encryptConfig.put("DecryptKeyUri","");
              encryptConfig.put("KeyServiceType","KMS");
              request.setEncryptConfig(encryptConfig.toJSONString());
              return client.getAcsResponse(request);
          }
      
          public static void main(String[] args) throws ClientException {
              String regionId = "cn-shanghai";  // Wilayah tempat layanan ApsaraVideo VOD diaktifkan.
              DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
              DefaultAcsClient client = new DefaultAcsClient(profile);
      
              SubmitTranscodeJobsResponse response;
              try {
                  response = submitTranscodeJobs(client);
                  System.out.println("RequestId is:"+response.getRequestId());
                  System.out.println("TranscodeTaskId is:"+response.getTranscodeTaskId());
                  System.out.println("TranscodeJobs is:"+ JSON.toJSON(response.getTranscodeJobs()));
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      }       
    2. Jika Anda telah mengonfigurasi notifikasi event untuk ApsaraVideo VOD, transkoding video selesai ketika Anda menerima pesan callback Transcoding of a Single-definition Video Completed atau Transcoding of All-definition Videos Completed.

  5. Lihat hasil enkripsi HLS.

    Setelah transkoding selesai, Anda dapat menggunakan tiga metode berikut untuk menentukan apakah enkripsi standar berhasil.

    • Metode 1: Masuk ke konsol ApsaraVideo VOD dan pilih Media Files > Audio/Video > Manage > Video URL. Pada halaman Video URL, jika video memiliki output dalam beberapa format, seperti file MP4 asli, periksa apakah aliran video m3u8 diberi label HLS Standard Encryption. Jika label tersebut ada, enkripsi HLS berhasil.视频安全-HLS标准加密5

    • Metode 2: Salin URL file M3U8 yang menggunakan HLS Standard Encryption. Jalankan perintah curl -v "URL file M3U8" untuk memeriksa konten M3U8. Jika konten tersebut berisi kunci URI="<URI dekripsi yang Anda teruskan untuk enkripsi standar, yaitu nilai parameter DecryptKeyUri>", video tersebut dilindungi oleh enkripsi HLS.

    • Metode 3: Panggil operasi GetTranscodeTask. Teruskan nilai parameter JobId yang dikembalikan di Langkah 4. Jika parameter TranscodeTemplateId yang dikembalikan merupakan ID kelompok templat transkoding yang Anda buat di Langkah 3 dan parameter TranscodeJobStatus bernilai TranscodeSuccess, enkripsi HLS berhasil.

Enkripsi dan penulisan ulang HLS (M3U8) (Direkomendasikan)

Setelah Anda mengaktifkan fitur enkripsi dan penulisan ulang M3U8, sistem secara otomatis menambahkan parameter enkripsi, seperti algoritma enkripsi, URI kunci, dan parameter otentikasi, ke tag #EXT-X-KEY dalam Media Playlist (file M3U8) protokol HLS. Saat klien mengurai file M3U8 yang ditulis ulang, klien tersebut menggunakan URI kunci dengan parameter otentikasi untuk meminta kunci dekripsi. Klien kemudian menggunakan kunci dan algoritma yang ditentukan untuk mendekripsi shard TS. Proses ini memberikan perlindungan akses terenkripsi untuk media streaming HLS.

Langkah 1: Aktifkan transmisi parameter enkripsi standar

Di konsol ApsaraVideo VOD, aktifkan Parameter Pass-through for HLS Encryption.

Mengaktifkan Parameter Pass-through for HLS Encryption memungkinkan Anda memodifikasi file M3U8 untuk HLS. Fitur ini memodifikasi URI dalam tag #EXT-X-KEY dengan menambahkan parameter dari permintaan klien. Nama parameter default adalah MtsHlsUriToken.

Prasyarat

Berbagi sumber daya lintas asal (CORS) telah dikonfigurasi. Untuk informasi selengkapnya, lihat Konfigurasi berbagi sumber daya lintas asal.

Penting

Fitur ini saat ini tidak didukung di Alibaba Gov Cloud.

Prosedur

  1. Masuk ke Konsol ApsaraVideo VOD.

  2. Di panel navigasi sebelah kiri, klik Configuration Management.

  3. Klik CDN Configuration > Domain Names untuk menuju halaman Domain Names.

  4. Temukan nama domain target dan klik Configure di kolom Actions.

  5. Di panel navigasi sebelah kiri halaman nama domain, klik Video Related.

  6. Di bagian Encrypted Playback, aktifkan sakelar Parameter Pass-through for HLS Encryption.p181836

Catatan
  • Setelah Anda mengaktifkan fitur ini, saat parameter enkripsi HLS ditransmisikan, sistem mengotentikasi permintaan Anda dengan menulis ulang parameter otentikasi token. Nama parameter yang ditulis ulang adalah MtsHlsUriToken, dan nilainya adalah test. Saat Alibaba Cloud CDN mendekripsi video untuk pemutaran, MtsHlsUriToken=test ditambahkan di akhir URI dalam tag #EXT-X-KEY file M3U8.

Langkah 2: Kirim permintaan yang mencakup parameter MtsHlsUriToken

Klien mengirim permintaan yang mencakup parameter MtsHlsUriToken ke titik kehadiran (POP) CDN untuk mengakses file M3U8.

Untuk mendapatkan MtsHlsUriToken, Anda harus membangun layanan token untuk menerbitkan token pengguna. Layanan ini menghasilkan MtsHlsUriToken.

Token yang dihasilkan oleh kode berikut adalah MtsHlsUriToken. Parameter berikut dalam kode contoh harus diubah sesuai kebutuhan Anda:

Perluas untuk melihat kode contoh Java

Parameter

Nilai input

ENCRYPT_KEY

Kunci enkripsi. String kustom sepanjang 16, 24, atau 32 karakter.

INIT_VECTOR

Offset enkripsi. String kustom sepanjang 16 karakter yang tidak boleh mengandung karakter khusus.

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Arrays;

public class PlayToken {
    // Parameter berikut tidak diperlukan jika Anda tidak menggunakan AES untuk menghasilkan token.
    private static String ENCRYPT_KEY = ""; // Kunci enkripsi. String kustom sepanjang 16, 24, atau 32 karakter.
    private static String INIT_VECTOR = ""; // Offset enkripsi. String kustom sepanjang 16 karakter yang tidak boleh mengandung karakter khusus.

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

        String serviceId = "12";
        PlayToken playToken = new PlayToken();
        String aesToken = playToken.generateToken(serviceId);
        //System.out.println("aesToken " + aesToken);
        //System.out.println(playToken.validateToken(aesToken));   // Bagian verifikasi dekripsi.
    }
    /**
     * Menghasilkan token berdasarkan parameter yang diteruskan.
     * Catatan:
     *  1. Parameter dapat berupa ID pengguna layanan Anda, jenis klien pemutaran, dan informasi lainnya.
     *  2. Token dihasilkan saat API token dipanggil.
     * @param args
     * @return
     */
    public String generateToken(String... args) throws Exception {
        if (null == args || args.length <= 0) {
            return null;
        }
        String base = StringUtils.join(Arrays.asList(args), "_");
        // Atur masa berlaku token selama 30 detik. Anda dapat menyesuaikan waktu kedaluwarsa.
        long expire = System.currentTimeMillis() + 30000L;
        base += "_" + expire;   // String kustom. Panjang string dasar adalah 16 karakter. Dalam contoh ini, timestamp menempati 13 karakter dan garis bawah (_) menempati 1 karakter. Oleh karena itu, Anda perlu meneruskan 2 karakter lagi. Anda juga dapat mengubah seluruh string sesuai kebutuhan untuk memastikan panjang string dasar adalah 16, 24, atau 32 karakter.
        // Hasilkan token.
        String token = encrypt(base, ENCRYPT_KEY);  // arg1 adalah string kustom yang akan dienkripsi, dan arg2 adalah kunci enkripsi.
        // Simpan token. Digunakan untuk memverifikasi validitas token selama dekripsi, seperti waktu kedaluwarsa dan jumlah kali token dapat digunakan.
        saveToken(token);
        return token;
    }

    /**
     * Memverifikasi validitas token.
     * Catatan:
     *  1. Sebelum API dekripsi mengembalikan kunci pemutaran, perlu memverifikasi legalitas dan validitas token.
     *  2. Kami sangat menyarankan agar Anda memverifikasi baik waktu kedaluwarsa maupun jumlah penggunaan valid token.
     * @param token
     * @return
     * @throws Exception
     */
    public boolean validateToken(String token) throws Exception {
        if (null == token || "".equals(token)) {
            return false;
        }
        String base = decrypt(token,ENCRYPT_KEY); // arg1 adalah string yang akan didekripsi, dan arg2 adalah kunci dekripsi.
        // Pertama, verifikasi periode validitas token.
        Long expireTime = Long.valueOf(base.substring(base.lastIndexOf("_") + 1));
        System.out.println("Verifikasi waktu:" + expireTime);
        if (System.currentTimeMillis() > expireTime) {
            return false;
        }
        // Dapatkan informasi token dari database untuk menentukan validitasnya. Anda dapat mengimplementasikan bagian ini sendiri.
        TokenInfo dbToken = getToken(token);
        // Periksa apakah token sudah digunakan.
        if (dbToken == null || dbToken.useCount > 0) {
            return false;
        }
        // Dapatkan informasi atribut bisnis untuk verifikasi.
        String businessInfo = base.substring(0, base.lastIndexOf("_"));
        String[] items = businessInfo.split("_");
        // Verifikasi legalitas informasi bisnis. Anda dapat mengimplementasikan bagian ini sendiri.
        return validateInfo(items);
    }
    /**
     * Menyimpan token ke database.
     * Anda dapat mengimplementasikan bagian ini sendiri.
     *
     * @param token
     */
    public void saveToken(String token) {
        //TODO: Simpan token.
    }
    /**
     * Menanyakan token.
     * Anda dapat mengimplementasikan bagian ini sendiri.
     *
     * @param token
     */
    public TokenInfo getToken(String token) {
        //TODO: Dapatkan informasi token dari database untuk memverifikasi validitas dan legalitasnya.
        return null;
    }
    /**
     * Memverifikasi validitas informasi bisnis. Anda dapat mengimplementasikan bagian ini sendiri.
     *
     * @param infos
     * @return
     */
    public boolean validateInfo(String... infos) {
        //TODO: Verifikasi validitas informasi, misalnya apakah UID valid.
        return true;
    }
    /**
     * Menghasilkan token menggunakan enkripsi AES.
     *
     * @param encryptStr  String yang akan dienkripsi.
     * @param encryptKey  Kunci enkripsi.
     * @return
     * @throws Exception
     */
    public String encrypt(String encryptStr, String encryptKey) throws Exception {
        IvParameterSpec e = new IvParameterSpec(INIT_VECTOR.getBytes("UTF-8"));
        SecretKeySpec skeySpec = new SecretKeySpec(encryptKey.getBytes("UTF-8"), "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, e);
        byte[] encrypted = cipher.doFinal(encryptStr.getBytes());
        return Base64.encodeBase64String(encrypted);
    }
    /**
     * Mendekripsi token menggunakan AES.
     *
     * @param encryptStr  String yang akan didekripsi.
     * @param decryptKey  Kunci dekripsi.
     * @return
     * @throws Exception
     */
    public String decrypt(String encryptStr, String decryptKey) throws Exception {

        IvParameterSpec e = new IvParameterSpec(INIT_VECTOR.getBytes("UTF-8"));
        SecretKeySpec skeySpec = new SecretKeySpec(decryptKey.getBytes("UTF-8"), "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, e);

        byte[] encryptByte = Base64.decodeBase64(encryptStr);
        byte[] decryptByte = cipher.doFinal(encryptByte);
        return new String(decryptByte);
    }
    /**
     * Informasi token. Anda dapat memberikan informasi lebih lanjut. Ini hanya contoh referensi.
     */
    class TokenInfo {
        // Jumlah kali token dapat digunakan. Di lingkungan terdistribusi, perhatikan masalah sinkronisasi.
        int useCount;
        // Konten token.
        String token;
    }}
                        
Catatan

Kode di atas merupakan contoh open source dan tidak melibatkan kode SDK atau layanan apa pun. Anda harus mengonfigurasi dan menyesuaikannya sesuai kebutuhan.

Langkah 3: Dekripsi dan putar file

Setelah POP CDN menerima permintaan dari klien, video akan didekripsi dan diputar jika otentikasi berhasil.

Jika nilai parameter MtsHlsUriToken yang dihasilkan di Langkah 2 adalah test, MtsHlsUriToken=test ditambahkan di akhir URI dalam tag #EXT-X-KEY file M3U8 saat CDN mendekripsi video untuk pemutaran.

Anda harus mengimplementasikan logika otentikasi. Untuk informasi selengkapnya, lihat kode contoh untuk layanan dekripsi saat enkripsi dan penulisan ulang M3U8 diaktifkan di Putar video.

Putar video

Enkripsi dan penulisan ulang M3U8 diaktifkan (Direkomendasikan)

  1. Siapkan layanan dekripsi.

    Siapkan layanan HTTP lokal untuk mendekripsi video.

    Panggil operasi Decrypt untuk mendekripsi kunci. PlainText dalam tanggapan adalah kunci data (DK). DK ini merupakan data hasil dekode Base64 dari PlainText yang dikembalikan oleh operasi GenerateDataKey.

    Untuk melakukan otentikasi keamanan pada alamat dekripsi, Anda dapat mengaktifkan Enkripsi dan penulisan ulang M3U8. Hal ini menambahkan lapisan perlindungan tambahan pada proses akses data HLS. Parameter penulisan ulang default adalah MtsHlsUriToken. Kode untuk menyiapkan layanan dekripsi berbeda tergantung pada apakah Anda mengaktifkan Enkripsi dan penulisan ulang M3U8.

    Perluas untuk melihat kode contoh Java

    Parameter berikut dalam kode contoh Java harus diubah sesuai kebutuhan Anda:

    Parameter

    Nilai input

    region

    ID wilayah. KMS dan ApsaraVideo VOD harus berada di wilayah yang sama. Misalnya, jika Anda menggunakan KMS dan ApsaraVideo VOD di Tiongkok (Shanghai), atur parameter ini menjadi cn-shanghai. Untuk informasi selengkapnya tentang ID wilayah lainnya, lihat ID wilayah ApsaraVideo VOD.

    AccessKey

    ID AccessKey dan rahasia AccessKey akun Alibaba Cloud atau pengguna RAM Anda. Untuk informasi selengkapnya tentang cara mendapatkan pasangan AccessKey, lihat Buat pasangan AccessKey.

    httpserver

    Nomor port yang ingin Anda gunakan untuk menjalankan layanan.

    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.http.ProtocolType;
    import com.aliyuncs.vod.model.v20170321.DecryptKMSDataKeyRequest;
    import com.aliyuncs.vod.model.v20170321.DecryptKMSDataKeyResponse;
    import com.aliyuncs.profile.DefaultProfile;
    import com.sun.net.httpserver.Headers;
    import com.sun.net.httpserver.HttpExchange;
    import com.sun.net.httpserver.HttpHandler;
    import com.sun.net.httpserver.HttpServer;
    import com.sun.net.httpserver.spi.HttpServerProvider;
    import org.apache.commons.codec.binary.Base64;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.HttpURLConnection;
    import java.net.InetSocketAddress;
    import java.net.URI;import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    public class HlsDecryptServer {
        private static DefaultAcsClient client;
        static {
            // Wilayah KMS. Harus sama dengan wilayah tempat video disimpan.
            String region = "";
            // Pasangan AccessKey yang digunakan untuk mengakses KMS.
            // Pasangan AccessKey akun Alibaba Cloud memiliki izin untuk memanggil semua operasi API. Kami menyarankan agar Anda menggunakan pasangan AccessKey pengguna RAM untuk memanggil operasi API atau melakukan O&M rutin.
            // Kami sangat menyarankan agar Anda tidak menyematkan ID AccessKey dan rahasia AccessKey secara langsung dalam kode proyek Anda. Jika tidak, pasangan AccessKey tersebut dapat bocor, sehingga mengancam keamanan semua sumber daya Anda.
            // Contoh ini menunjukkan cara membaca pasangan AccessKey dari variabel lingkungan untuk mengotentikasi akses API. Sebelum menjalankan kode, konfigurasikan variabel lingkungan ALIBABA_CLOUD_ACCESS_KEY_ID dan ALIBABA_CLOUD_ACCESS_KEY_SECRET.
            String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
            String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
            client = new DefaultAcsClient(DefaultProfile.getProfile(region, accessKeyId, accessKeySecret));
        }
        /**
         * Catatan:
         * 1. Menerima permintaan dekripsi dan mendapatkan kunci ciphertext serta token pengguna.
         * 2. Memanggil operasi dekripsi KMS untuk mendapatkan kunci plaintext.
         * 3. Mengembalikan kunci plaintext yang telah didekode Base64.
         */
        public class HlsDecryptHandler implements HttpHandler {
            /**
             * Memproses permintaan dekripsi.
             * @param httpExchange
             * @throws IOException
             */
            public void handle(HttpExchange httpExchange) throws IOException {
                String requestMethod = httpExchange.getRequestMethod();
                if ("GET".equalsIgnoreCase(requestMethod)) {
                    // Verifikasi validitas token.
                    String token = getMtsHlsUriToken(httpExchange);
                    boolean validRe = validateToken(token);
                    if (!validRe) {
                        return;
                    }
                    // Dapatkan kunci ciphertext dari URL.
                    String ciphertext = getCiphertext(httpExchange);
                    if (null == ciphertext)
                        return;
                    // Dekripsi kunci dari KMS dan dekode Base64-nya.
                    byte[] key = decrypt(ciphertext);
                    // Atur header.
                    setHeader(httpExchange, key);
                    // Kembalikan kunci yang telah didekode Base64.
                    OutputStream responseBody = httpExchange.getResponseBody();
                    responseBody.write(key);
                    responseBody.close();
                }
            }
            private void setHeader(HttpExchange httpExchange, byte[] key) throws IOException {
                Headers responseHeaders = httpExchange.getResponseHeaders();
                responseHeaders.set("Access-Control-Allow-Origin", "*");
                httpExchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, key.length);
            }
            /**
             * Memanggil operasi dekripsi KMS untuk mendekripsi kunci dan mendekode Base64 plaintext.
             * @param ciphertext
             * @return
             */
            private byte[] decrypt(String ciphertext) {
                DecryptKMSDataKeyRequest request = new DecryptKMSDataKeyRequest();
                request.setCipherText(ciphertext);
                request.setProtocol(ProtocolType.HTTPS);
                try {
                    DecryptKMSDataKeyResponse response = client.getAcsResponse(request);
                    String plaintext = response.getPlaintext();
                    System.out.println("PlainText: " + plaintext);
                    // Catatan: plaintext harus didekode Base64.
                    return Base64.decodeBase64(plaintext);
                } catch (ClientException e) {
                    e.printStackTrace();
                    return null;
                }
            }
            /**
             * Mendapatkan parameter kunci ciphertext dari URL.
             * @param httpExchange
             * @return
             */
            private String getCiphertext(HttpExchange httpExchange) {
                URI uri = httpExchange.getRequestURI();
                String queryString = uri.getQuery();
                String pattern = "CipherText=(\\w*)";
                Pattern r = Pattern.compile(pattern);
                Matcher m = r.matcher(queryString);
                if (m.find())
                    return m.group(1);
                else {
                    System.out.println("Parameter CipherText Tidak Ditemukan");
                    return null;
                }
            }
            
              /**
             * Memverifikasi validitas token. Ini diperlukan untuk Enkripsi dan penulisan ulang M3U8.
             * @param token
             * @return
             */
            private boolean validateToken(String token) {
                if (null == token || "".equals(token)) {
                    return false;
                }
                //TODO: Implementasikan verifikasi validitas token.
                return true;
            }
            /**
             * Mendapatkan parameter token. Ini diperlukan untuk Enkripsi dan penulisan ulang M3U8.
             *
             * @param httpExchange
             * @return
             */
            private String getMtsHlsUriToken(HttpExchange httpExchange) {
                URI uri = httpExchange.getRequestURI();
                String queryString = uri.getQuery();
                String pattern = "MtsHlsUriToken=(\\w*)";
                Pattern r = Pattern.compile(pattern);
                Matcher m = r.matcher(queryString);
                if (m.find())
                    return m.group(1);
                else {
                    System.out.println("Parameter MtsHlsUriToken Tidak Ditemukan");
                    return null;
                }
            }
        }
        /**
         * Menjalankan layanan.
         *
         * @throws IOException
         */
        private void serviceBootStrap() throws IOException {
            HttpServerProvider provider = HttpServerProvider.provider();
            // Anda dapat menyesuaikan port pendengar. Dapat menerima hingga 30 permintaan secara bersamaan.
            HttpServer httpserver = provider.createHttpServer(new InetSocketAddress(8099), 30);
            httpserver.createContext("/", new HlsDecryptHandler());
            httpserver.start();
            System.out.println("server dekripsi hls dimulai");
        }
        public static void main(String[] args) throws IOException {
            HlsDecryptServer server = new HlsDecryptServer();
            server.serviceBootStrap();
        }}
  2. Dapatkan URL pemutaran video dan kredensial.

    Panggil operasi GetVideoPlayAuth untuk mendapatkan kredensial pemutaran atau panggil operasi GetPlayInfo untuk mendapatkan URL pemutaran.

  3. Putar video terenkripsi.

    Enkripsi HLS kompatibel dengan semua pemutar HLS. Anda dapat menggunakan pemutar yang dikembangkan sendiri atau Pemutar Video Apsara untuk memutar video terenkripsi.

    Jika Anda menggunakan Pemutar Video Apsara, Anda harus mendapatkan token dan informasi otentikasi sesuai persyaratan Pemutar Video Apsara sebelum pemutaran. Untuk informasi selengkapnya, lihat Putar video terenkripsi. Jika Anda menggunakan pemutar selain Pemutar Video Apsara, Anda harus mengimplementasikan logika pemutaran.

    Bagian berikut menjelaskan proses internal penggunaan Pemutar Video Apsara untuk pemutaran uji coba:

    Enkripsi dan penulisan ulang M3U8 diaktifkan (Direkomendasikan)

    Proses

    • Pemutar mengurai tag EXT-X-KEY dalam file M3U8 untuk mendapatkan URI kunci dekripsi. URI ini sesuai dengan nilai parameter DecryptKeyUri dalam EncryptConfig.

    • Untuk mencegah akses tidak sah, pemutar harus menyertakan informasi otentikasi, yang diteruskan menggunakan parameter MtsHlsUriToken, saat meminta API dekripsi.

    • Pemutar secara otomatis meminta API dekripsi untuk mendapatkan kunci, mendekripsi file TS terenkripsi, lalu memulai pemutaran.

    Contoh

    • URL pemutaran video adalah https://demo.aliyundoc.com/encrypt-stream****-hd.m3u8. Permintaan harus menyertakan parameter MtsHlsUriToken.

    • URL permintaan akhir adalah https://demo.aliyundoc.com/encrypt-stream****-hd.m3u8?MtsHlsUriToken=<token>.

    • Alamat dekripsi adalah https://demo.aliyundoc.com?CipherText=ZjJmZGViNzUtZWY1Mi00Y2RlLTk3MTMtOT****.

    • URL permintaan dekripsi akhir adalah https://demo.aliyundoc.com?CipherText=ZjJmZGViNzUtZWY1Mi00Y2RlLTk3MTMtOT****&MtsHlsUriToken=<issued_token>.

Enkripsi M3U8 dan Penulisan Ulang Dinonaktifkan

  1. Siapkan layanan dekripsi.

    Siapkan layanan HTTP lokal untuk mendekripsi video.

    Panggil operasi Decrypt untuk mendekripsi kunci. PlainText dalam tanggapan adalah kunci data (DK). DK ini merupakan data hasil dekode Base64 dari PlainText yang dikembalikan oleh operasi GenerateDataKey.

    Berikut adalah contohnya:

    Perluas untuk melihat kode contoh Java

    Parameter berikut dalam kode contoh Java harus diubah sesuai kebutuhan Anda:

    Parameter

    Nilai input

    region

    ID wilayah. KMS dan ApsaraVideo VOD harus berada di wilayah yang sama. Misalnya, jika Anda menggunakan KMS dan ApsaraVideo VOD di Tiongkok (Shanghai), atur parameter ini menjadi cn-shanghai. Untuk informasi selengkapnya tentang ID wilayah lainnya, lihat ID wilayah ApsaraVideo VOD.

    AccessKey

    ID AccessKey dan rahasia AccessKey akun Alibaba Cloud atau pengguna RAM Anda. Untuk informasi selengkapnya tentang cara mendapatkan pasangan AccessKey, lihat Buat pasangan AccessKey.

    httpserver

    Nomor port yang ingin Anda gunakan untuk menjalankan layanan.

    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.http.ProtocolType;
    import com.aliyuncs.profile.DefaultProfile;
    import com.aliyuncs.vod.model.v20170321.DecryptKMSDataKeyRequest;
    import com.aliyuncs.vod.model.v20170321.DecryptKMSDataKeyResponse;
    import com.sun.net.httpserver.Headers;
    import com.sun.net.httpserver.HttpExchange;
    import com.sun.net.httpserver.HttpHandler;
    import com.sun.net.httpserver.HttpServer;
    import com.sun.net.httpserver.spi.HttpServerProvider;
    import org.apache.commons.codec.binary.Base64;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.HttpURLConnection;
    import java.net.InetSocketAddress;
    import java.net.URI;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class HlsDecryptServerNoToken {
    
        private static DefaultAcsClient client;
        static {
            // Wilayah KMS. Harus sama dengan wilayah tempat video disimpan.
            String region = "cn-beijing";
            // Pasangan AccessKey yang digunakan untuk mengakses KMS.
            // Pasangan AccessKey akun Alibaba Cloud memiliki izin untuk memanggil semua operasi API. Kami menyarankan Anda menggunakan pasangan AccessKey pengguna RAM untuk memanggil operasi API atau melakukan O&M rutin.
            // Kami sangat menyarankan agar Anda tidak menyematkan ID AccessKey dan rahasia AccessKey secara langsung dalam kode proyek Anda. Jika tidak, pasangan AccessKey tersebut dapat bocor, sehingga mengancam keamanan semua sumber daya Anda.
            // Contoh ini menunjukkan cara membaca pasangan AccessKey dari variabel lingkungan untuk mengotentikasi akses API. Sebelum menjalankan kode, konfigurasikan variabel lingkungan ALIBABA_CLOUD_ACCESS_KEY_ID dan ALIBABA_CLOUD_ACCESS_KEY_SECRET.
            String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
            String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
            client = new DefaultAcsClient(DefaultProfile.getProfile(region, accessKeyId, accessKeySecret));
        }
        /**
         * Catatan:
         * 1. Menerima permintaan dekripsi dan mendapatkan kunci ciphertext dan token.
         * 2. Memanggil operasi dekripsi KMS untuk mendapatkan kunci plaintext.
         * 3. Mengembalikan kunci plaintext yang telah didekode Base64.
         */
        public class HlsDecryptHandler implements HttpHandler {
            /**
             * Memproses permintaan dekripsi.
             * @param httpExchange
             * @throws IOException
             */
            public void handle(HttpExchange httpExchange) throws IOException {
                String requestMethod = httpExchange.getRequestMethod();
                if ("GET".equalsIgnoreCase(requestMethod)) {
    
                    // Dapatkan kunci ciphertext dari URL.
                    String ciphertext = getCiphertext(httpExchange);
                    System.out.println(ciphertext);
                    if (null == ciphertext)
                        return;
                    // Dekripsi kunci dari KMS dan dekode Base64-nya.
                    byte[] key = decrypt(ciphertext);
                    // Atur header.
                    setHeader(httpExchange, key);
                    // Kembalikan kunci yang telah didekode Base64.
                    OutputStream responseBody = httpExchange.getResponseBody();
                    responseBody.write(key);
                    responseBody.close();
                }
            }
            private void setHeader(HttpExchange httpExchange, byte[] key) throws IOException {
                Headers responseHeaders = httpExchange.getResponseHeaders();
                responseHeaders.set("Access-Control-Allow-Origin", "*");
                httpExchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, key.length);
            }
            /**
             * Memanggil operasi dekripsi KMS untuk mendekripsi kunci dan mendekode plaintext-nya dengan Base64.
             * @param ciphertext
             * @return
             */
            private byte[] decrypt(String ciphertext) {
    
                DecryptKMSDataKeyRequest request = new DecryptKMSDataKeyRequest();
                request.setCipherText(ciphertext);
                request.setProtocol(ProtocolType.HTTPS);
                try {
                    DecryptKMSDataKeyResponse response = client.getAcsResponse(request);
                    String plaintext = response.getPlaintext();
                    System.out.println("PlainText: " + plaintext);
                    // Catatan: plaintext harus didekode Base64.
                    return Base64.decodeBase64(plaintext);
                } catch (ClientException e) {
                    e.printStackTrace();
                    return null;
                }
            }
    
            /**
             * Mendapatkan parameter kunci ciphertext dari URL.
             * @param httpExchange
             * @return
             */
            private String getCiphertext(HttpExchange httpExchange) {
                URI uri = httpExchange.getRequestURI();
                String queryString = uri.getQuery();
                String pattern = "CipherText=(\\w*)";
                Pattern r = Pattern.compile(pattern);
                Matcher m = r.matcher(queryString);
                if (m.find())
                    return m.group(1);
                else {
                    System.out.println("Parameter CipherText Tidak Ditemukan");
                    return null;
                }
            }
        }
    
        /**
         * Menjalankan layanan.
         *
         * @throws IOException
         */
        private void serviceBootStrap() throws IOException {
            HttpServerProvider provider = HttpServerProvider.provider();
            // Anda dapat menyesuaikan port pendengar. Dapat menerima hingga 30 permintaan secara bersamaan.
            HttpServer httpserver = provider.createHttpServer(new InetSocketAddress(8099), 30);
            httpserver.createContext("/", new HlsDecryptHandler());
            httpserver.start();
            System.out.println("server dekripsi hls dimulai");
        }
        public static void main(String[] args) throws IOException {
            HlsDecryptServerNoToken server = new HlsDecryptServerNoToken();
            server.serviceBootStrap();
        }}
    
  2. Dapatkan URL pemutaran video dan kredensial.

    Panggil operasi GetVideoPlayAuth untuk mendapatkan kredensial pemutaran atau panggil operasi GetPlayInfo untuk mendapatkan URL pemutaran.

  3. Putar video terenkripsi.

    Enkripsi HLS kompatibel dengan semua pemutar HLS. Anda dapat menggunakan pemutar yang dikembangkan sendiri atau Pemutar Video Apsara untuk memutar video terenkripsi.

    Jika Anda menggunakan Pemutar Video Apsara, Anda harus mendapatkan token dan informasi otentikasi sesuai persyaratan Pemutar Video Apsara sebelum pemutaran. Untuk informasi selengkapnya, lihat Putar video terenkripsi. Jika Anda menggunakan pemutar selain Pemutar Video Apsara, Anda harus mengimplementasikan logika pemutaran.

    Bagian berikut menjelaskan proses internal penggunaan Pemutar Video Apsara untuk pemutaran uji coba:

    Enkripsi M3U8 dan Penulisan Ulang Dinonaktifkan

    Proses

    • Pemutar mengurai tag EXT-X-KEY dalam file M3U8 untuk mendapatkan URI kunci dekripsi. URI ini sesuai dengan nilai parameter DecryptKeyUri dalam EncryptConfig.

    • Pemutar secara otomatis meminta API dekripsi untuk mendapatkan kunci, mendekripsi file TS terenkripsi, lalu memulai pemutaran.

    Contoh

    • URL pemutaran video adalah https://demo.aliyundoc.com/encrypt-stream****-hd.m3u8.

    • URL permintaan akhir adalah https://demo.aliyundoc.com/encrypt-stream****-hd.m3u8.

    • Alamat dekripsi adalah https://demo.aliyundoc.com?CipherText=ZjJmZGViNzUtZWY1Mi00Y2RlLTk3MTMtOT****.

    • URL permintaan dekripsi akhir adalah https://demo.aliyundoc.com?CipherText=ZjJmZGViNzUtZWY1Mi00Y2RlLTk3MTMtOT****.

Referensi