Tüm Ürünler
Search
Belge Merkezi

ApsaraVideo VOD:HLS şifreleme

Son Güncelleme:Oct 05, 2026

HLS şifreleme AES-128 kullanır ve tüm HLS oynatıcılarla uyumludur. Anahtar yönetimi ve belirteç hizmeti ile birleştirildiğinde, çevrimiçi eğitim ve özel içerik akışı gibi yüksek güvenlik gerektiren senaryolar için uygundur.

Nasıl çalışır

ApsaraVideo VOD zarf şifrelemeyi kullanır. Hizmet sağlayıcı, Alibaba Cloud Key Management Service (KMS) kullanarak bir veri anahtarı (DK) ve bir zarflanmış veri anahtarı (EDK) oluşturur. DK videoyu şifreler ve EDK bunun yanında saklanır. Oynatma sırasında istemci, videonun şifresini çözmek için DK'yı şifre çözme hizmetinden alır.

Şifre çözme URL'sini güvence altına almak için M3U8 şifreleme ve yeniden yazmayı etkinleştirin; bu işlem HLS veri erişim sürecine ek bir koruma katmanı ekler. Varsayılan yeniden yazılan parametre MtsHlsUriToken şeklindedir. Bu özelliğin nasıl etkinleştirileceğini ve nasıl çalıştığını öğrenmek için bkz. M3U8 şifreleme ve yeniden yazma.

Önkoşullar

Anahtar kavramlar


Kavram


Açıklama


Resource Access Management (RAM)


Kullanıcı kimliklerini yönetmenize ve kaynaklarınıza erişimi kontrol etmenize olanak tanıyan bir Alibaba Cloud hizmetidir. Daha fazla bilgi için bkz. RAM nedir.


Key Management Service (KMS)


Anahtar yönetimi ve veri şifreleme için tek duraklı bir Alibaba Cloud platformudur. Verilerinizi korumak ve kimlik bilgilerini yönetmek için basit, güvenilir, güvenli ve uyumlu bir çözüm sunar. Daha fazla bilgi için bkz. Key Management Service nedir.


Veri anahtarı (DK)


Verileri şifrelemek için kullanılan düz metin anahtardır. Daha fazla bilgi için bkz. Terimler.


Zarflanmış veri anahtarı (EDK)


Zarf şifreleme ile korunan şifrelenmiş veri anahtarıdır. Daha fazla bilgi için bkz. Terimler.

Şifreleme ve şifre çözme iş akışı

Yükleme ve şifreleme iş akışı

视频安全-HLS标准加密3

Şifre çözme ve oynatma iş akışı

M3U8 yeniden yazma etkin (Önerilen)

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

M3U8 yeniden yazma devre dışı

视频安全-HLS标准加密2

Videoyu şifreleme

  1. Videonuzu yükleyin ve geri arama alın.

    HLS Şifrelemesini destekleyen videoların otomatik olarak kodunun dönüştürülmesini önlemek için, videoları ApsaraVideo VOD'a yüklerken yerleşik No Transcoding şablon grubunu kullanmanız gerekir. Bu işlem yükleme sırasında otomatik kod dönüştürmeyi engeller.

    1. ApsaraVideo VOD konsolunu kullanarak video yüklemek için bkz. ApsaraVideo VOD konsolunda dosya yükleme. Sunucu tarafı API kullanarak video yüklemek için bkz. Medya yükleme.

    2. ApsaraVideo VOD için olay bildirimlerini yapılandırın. Video yükleme tamamlandı olayına ait bir geri arama iletisi, videonun ApsaraVideo VOD'a yüklendiğini gösterir. Olay bildirimlerinin nasıl yapılandırılacağı hakkında bilgi için bkz. Olay bildirimleri.

  2. Bir şifreleme hizmeti kurun.

    1. Bir hizmet anahtarı oluşturun.

      Hizmet anahtarı, KMS'deki birincil şifreleme anahtarıdır ve HLS Şifrelemesi için anahtarlar oluşturmak üzere kullanılmalıdır. Bir hizmet anahtarı oluşturmazsanız GenerateKMSDataKey işlemi hata verir.

      1. Sayfanın sol üst köşesinde, hizmet anahtarını oluşturmak istediğiniz bölgeye geçmek için bölge kimliğine tıklayın.

        Not

        Hizmet anahtarı, videonuzun kaynak sunucusuyla aynı bölgede bulunmalıdır. Örneğin, videonuz Çin (Şanghay) bölgesinde depolanıyorsa hizmet anahtarı da Çin (Şanghay) bölgesinde oluşturulmalıdır.

        Kullanılabilir bölgeler Çin (Şanghay), Çin (Pekin), Çin (Shenzhen), Japonya (Tokyo), Singapur, Endonezya (Cakarta), Hindistan (Mumbai) ve Almanya (Frankfurt) şeklindedir.

      2. ApsaraVideo VOD konsoluna gidin. Sol gezinme bölmesinde Configuration Management > Media Processing > HLS Standard Encryption seçeneklerini seçin.

      3. HLS Şifreleme sayfasında Create Service Key seçeneğine tıklayın.

        Hizmet anahtarı oluşturulduktan sonra bir onay mesajı görünür. Ardından anahtarı Key Information bölümünde görüntüleyebilirsiniz.

        Not

        Başarılı bir mesaj görünür ancak anahtarı görüntüleyemiyorsanız, bunun nedeni eksik bir hizmet bağlantılı rol olabilir. Rolü geri yüklemek için ApsaraVideo VOD'u yeniden yetkilendirebilir ve ardından hizmet anahtarını görüntülemek için sayfayı yenileyebilirsiniz.

    2. Bir veri anahtarı (DK) oluşturmak için bir API işlemi çağırın.

      Bir veri anahtarı (DK) ve bir zarflanmış veri anahtarı (EDK) oluşturmak için GenerateKMSDataKey işlemini çağırın. Herhangi bir parametre iletmeniz gerekmez. Başarılı bir çağrıdan sonra yanıtta bulunan Plaintext alanında DK, CiphertextBlob alanında ise AES-128 formatındaki EDK yer alır. HLS Şifreleme kod dönüştürme işi için CiphertextBlob değerini önbelleğe alın.

  3. HLS Şifrelemesi için bir kod dönüştürme şablon grubu oluşturun.

    HLS Şifreleme süreci iki kod dönüştürme şablon grubu gerektirir: yerleşik No Transcoding şablon grubu ve HLS Şifrelemesi için özel bir kod dönüştürme şablon grubu. Özel bir kod dönüştürme şablon grubu oluşturmak için aşağıdaki adımları uygulayın:

    1. ApsaraVideo VOD konsoluna gidin. Sol gezinme bölmesinde Configuration Management > Media Processing > Transcoding Template Groups seçeneklerini seçin.

    2. Kod Dönüştürme Şablon Grupları sayfasında HLS Şifrelemesi için bir kod dönüştürme şablon grubu oluşturun.

      Encapsulation Format seçeneğini hls olarak ayarlayın. Advanced Parameters bölümünde Video Encryption seçeneğini etkinleştirin ve Alibaba Cloud Encryption seçeneğini belirleyin. Diğer parametreleri gerektiği şekilde yapılandırın. Parametreler hakkında daha fazla bilgi için bkz. Kod dönüştürme şablonları.

    3. Şablon grubu oluşturulduktan sonra Kod Dönüştürme Şablon Grupları sayfasındaki listede yeni şablon grubunu bulun ve ID değerini kaydedin. Bu şablon grubu kimliği şifreleme yapılandırması için gereklidir.

  4. Bir HLS Şifreleme kod dönüştürme işi gönderin.

    1. Bir HLS Şifreleme kod dönüştürme işi göndermek için SubmitTranscodeJobs işlemini çağırın.

      Java örnek kodu

      Aşağıdaki Java örnek kodunda parametreleri gereksinimlerinize göre değiştirin:


      Parametre


      Değer


      request.setTemplateGroupId("")


      Adım 3 içinde oluşturduğunuz HLS Şifrelemesi için kod dönüştürme şablon grubunun kimliği.


      request.setVideoId("")


      Adım 1 içinde yüklediğiniz videonun kimliği.


      encryptConfig.put("CipherText","")


      Adım 2 içinde döndürülen CiphertextBlob değeri.


      encryptConfig.put("DecryptKeyUri","")

      Anahtar URI'si. URI, şifre çözme hizmeti URL'si ve CiphertextBlob değeri birleştirilerek oluşturulur. Örneğin, hizmetiniz yerel olarak 8099 numaralı bağlantı noktasında çalışıyorsa anahtar URI'si aşağıdaki gibidir:

      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 {
          // An AccessKey pair of an Alibaba Cloud account has permissions to call all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M.
          // We strongly recommend that you do not hard-code the AccessKey ID and AccessKey secret in your project code. Otherwise, the AccessKey pair may be leaked and the security of all your resources may be compromised.
          // This example shows how to use environment variables to obtain the AccessKey pair for authentication. Before you run the sample code, configure the ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variables.
          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";  // The region for ApsaraVideo VOD.
              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. Olay bildirimlerini yapılandırdıysanız Single Definition Transcoding Complete veya Transcode complete olayına ait bir geri callback iletisi, kod dönüştürme işinin tamamlandığını gösterir.

  5. HLS Şifreleme sonucunu doğrulayın.

    Kod dönüştürme işi tamamlandıktan sonra şifrelemeyi doğrulamak için aşağıdaki yöntemlerden birini kullanın.

    • Yöntem 1: ApsaraVideo VOD konsoluna gidin. Audio/Video dosyasının ayrıntılar sayfasına gidin ve Video URL sekmesine tıklayın. Video URL listesinde M3U8 çıkış dosyasının format sütununda bir HLS Encryption etiketi olup olmadığını kontrol edin. Bu etiketin varlığı şifrelemenin başarılı olduğunu doğrular.

    • Yöntem 2: HLS Standard Encryption etiketine sahip M3U8 dosyasının URL'sini kopyalayın. M3U8 içeriğini almak için curl -v "M3U8 dosyasının URL'si" komutunu çalıştırın. İçerikte aşağıdaki anahtar bilgileri kontrol edin: URI="<the decryption URI that you provided as the DecryptKeyUri parameter value>". Bu bilgiler mevcutsa şifreleme başarılı olmuştur.

    • Yöntem 3: GetTranscodeTask işlemini çağırın ve Adım 4 içinde döndürülen JobId parametresinin değerini iletin. Yanıttaki TranscodeTemplateId değeri Adım 3 içinde oluşturduğunuz kod dönüştürme şablon grubunun kimliğiyle eşleşiyor ve TranscodeJobStatus değeri TranscodeSuccess ise şifreleme başarılı olmuştur.

HLS (M3U8) şifreleme ve yeniden yazma (Önerilen)

M3U8 şifreleme ve yeniden yazma etkinleştirildiğinde sistem, HLS Medya Oynatma Listesine (M3U8 dosyası) #EXT-X-KEY etiketine algoritma, anahtar URI'si ve kimlik doğrulama parametreleri dahil olmak üzere şifreleme parametrelerini otomatik olarak ekler. İstemci yeniden yazılmış M3U8 dosyasını ayrıştırdığında, şifre çözme anahtarını istemek için kimlik doğrulama parametrelerine sahip anahtar URI'sini kullanır ve ardından aktarım akışı (TS) segmentlerinin şifresini belirtilen algoritmayla çözer.

Adım 1: HLS şifrelemesi için parametre geçişini etkinleştirme

ApsaraVideo VOD konsolunda Parameter Pass-through for HLS Encryption seçeneğini etkinleştirin.

Parameter Pass-through for HLS Encryption seçeneğini etkinleştirdikten sonra ApsaraVideo VOD, M3U8 dosyasını yeniden yazar ve istemci isteğinden gelen parametreleri ekleyerek #EXT-X-KEY etiketindeki URI'yi değiştirir. Varsayılan parametre adı MtsHlsUriToken şeklindedir.

Önkoşullar

Çapraz kaynak paylaşımını (CORS) yapılandırdınız. Daha fazla bilgi için bkz. Çapraz kaynak paylaşımını yapılandırma.

Önemli

Bu özellik Alibaba Cloud Gov Cloud'da kullanılamaz.

Yordam

  1. ApsaraVideo VOD konsoluna gidin.

  2. Sol gezinme bölmesinde Configuration Management seçeneğine tıklayın.

  3. CDN Configuration > Domain Names seçeneklerine tıklayarak Domain Names sayfasına gidin.

  4. Yönetmek istediğiniz alan adını bulun ve Actions sütunundaki configure seçeneğine tıklayın.

  5. Alan adının yapılandırma sayfasında sol gezinme bölmesinde Video Related seçeneğine tıklayın.

  6. encrypted playback bölümünde Parameter Pass-through for HLS Encryption anahtarını açın. Varsayılan olarak bu anahtar kapalıdır ve parametre adı MtsHlsUriToken şeklindedir.

Not
  • Bu özelliği etkinleştirdikten sonra ApsaraVideo VOD, belirteç parametresini yeniden yazarak kimlik doğrulamasını gerçekleştirir. Yeniden yazılan parametre MtsHlsUriToken şeklindedir ve değeri test olur. Şifresi çözülmüş oynatma sırasında dağıtım noktası (POP), M3U8 dosyasının #EXT-X-KEY etiketindeki URI'ye MtsHlsUriToken=test ekler.

Adım 2: MtsHlsUriToken içeren istek gönderme

M3U8 dosyasına erişmek için istemci, MtsHlsUriToken parametresini içeren bir isteği bir dağıtım noktasına (POP) gönderir.

Kullanıcılara MtsHlsUriToken oluşturup vermek için bir belirteç hizmeti oluşturmanız gerekir.

Aşağıdaki kod MtsHlsUriToken oluşturur. İş gereksinimlerinize göre aşağıdaki parametreleri değiştirmeniz gerekir:

Java örnek kodu


Parametre


Açıklama


ENCRYPT_KEY


Şifreleme anahtarı. 16, 24 veya 32 karakter uzunluğunda özel bir dize.


INIT_VECTOR


Şifreleme ofseti. Özel karakter içermeyen 16 karakterlik özel bir dize.

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 {
    // These parameters are required only for AES token generation.
    private static String ENCRYPT_KEY = "";
    private static String INIT_VECTOR = "";
    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));   // Verify the decryption.
    }
    /**
     * Generates a token based on the passed parameters.
     * Note:
     *  1. The parameters can include information such as the user ID of your service and the playback client type.
     *  2. The token is generated by a call to your token service API.
     * @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), "_");
        // Sets the token to expire after 30 seconds. You can adjust the expiration time.
        long expire = System.currentTimeMillis() + 30000L;
        base += "_" + expire;   // A custom string. The final length of `base` must be 16, 24, or 32 characters. In this example, the timestamp is 13 characters and the underscore (_) is 1 character, so you must pass a 2-character string. You can modify this string as needed.
        // Generate the token.
        String token = encrypt(base, ENCRYPT_KEY);  // 'encryptStr' is the custom string to encrypt and 'encryptKey' is the encryption key.
        // Save the token to validate it during decryption, for example, its expiration time and number of uses.
        saveToken(token);
        return token;
    }
    /**
     * Validates the token.
     * Note:
     *  1. Your decryption service must validate the token's legitimacy and validity before returning the playback key.
     *  2. We strongly recommend that you also validate the token's expiration time and number of valid uses.
     * @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); // 'encryptStr' is the string to decrypt and 'decryptKey' is the decryption key.
        // First, validate the token's expiration time.
        Long expireTime = Long.valueOf(base.substring(base.lastIndexOf("_") + 1));
        System.out.println("Time validation: " + expireTime);
        if (System.currentTimeMillis() > expireTime) {
            return false;
        }
        // Obtain token information from the database to determine its validity. You must implement this part.
        TokenInfo dbToken = getToken(token);
        // Check whether the token has been used.
        if (dbToken == null || dbToken.useCount > 0) {
            return false;
        }
        // Obtain the business attribute information for validation.
        String businessInfo = base.substring(0, base.lastIndexOf("_"));
        String[] items = businessInfo.split("_");
        // Validate the legitimacy of the business information. You must implement this part.
        return validateInfo(items);
    }
    /**
     * Saves the token to the database.
     * You must implement this part.
     *
     * @param token
     */
    public void saveToken(String token) {
        //TODO: Store the token.
    }
    /**
     * Queries the token.
     * You must implement this part.
     *
     * @param token
     */
    public TokenInfo getToken(String token) {
        //TODO: Obtain token information from the database for validity and legitimacy checks.
        return null;
    }
    /**
     * Validates the business information. You must implement this part.
     *
     * @param infos
     * @return
     */
    public boolean validateInfo(String... infos) {
        //TODO: Validate the information, for example, whether the UID is valid.
        return true;
    }
    /**
     * Generates a token by using AES encryption.
     *
     * @param encryptStr  The string to encrypt.
     * @param encryptKey  The encryption key.
     * @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);
    }
    /**
     * Decrypts a token by using AES.
     *
     * @param encryptStr  The string to decrypt.
     * @param decryptKey  The decryption key.
     * @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);
    }
    /**
     * Token information. You can add more information based on your business logic. This is for reference only.
     */
    class TokenInfo {
        // The number of times the token can be used. Note synchronization issues in a distributed environment.
        int useCount;
        // The token content.
        String token;
    }}
                        
Not

Yukarıdaki örnek kod yalnızca referans amaçlıdır. Herhangi bir SDK veya hizmet kodu içermez. İş gereksinimlerinize göre yapılandırmanız ve ayarlamanız gerekir.

Adım 3: Dosyanın şifresini çözme ve oynatma

İstemciden bir istek alındığında dağıtım noktası (POP) bunu kimlik doğrular. Kimlik doğrulama başarılı olursa POP dosyanın şifresini çözer ve oynatır.

Adım 2'de oluşturulan MtsHlsUriToken parametresinin değeri test ise şifresi çözülmüş oynatma sırasında POP, M3U8 dosyasının #EXT-X-KEY etiketindeki URI'ye MtsHlsUriToken=test ekler.

Kimlik doğrulama mantığını uygulamanız gerekir. Referans için bkz. Videoları oynatma bölümündeki M3U8 şifreleme ve yeniden yazma için şifre çözme hizmeti örnek kodu.

Videoyu oynatma

M3U8 yeniden yazma ile (önerilen)

  1. Bir şifre çözme hizmeti kurun.

    Videoların şifresini çözmek için yerel bir HTTP hizmeti kurun.

    Veri anahtarının şifresini çözmek için DecryptKMSDataKey işlemini çağırın. Yanıttaki veri anahtarı olan PlainText, GenerateKMSDataKey işlemi tarafından döndürülen PlainText değerinin Base64 kodu çözülmüş halidir.

    Şifre çözme URL'lerini doğrulayarak ek bir güvenlik katmanı eklemek için M3U8 şifreleme ve yeniden yazmayı etkinleştirin. Bu özellik, anahtar istek URL'sine bir belirteç ekler. Varsayılan parametre adı MtsHlsUriToken şeklindedir. Şifre çözme hizmeti uygulamanız bu özelliğin etkin olup olmadığına bağlıdır.

    Java örnek kodunu genişletmek için tıklayın

    Aşağıdaki tabloda özelleştirebileceğiniz örnek koddaki parametreler açıklanmaktadır.


    Parametre


    Açıklama


    region


    Bölge kimliği. KMS hizmetinin bölgesi, ApsaraVideo VOD videonuzun depolandığı bölgeyle aynı olmalıdır. Örneğin, Çin (Şanghay) için bu parametreyi cn-shanghai olarak ayarlayın. Diğer bölge kimlikleri hakkında daha fazla bilgi için bkz. ApsaraVideo VOD bölge kimlikleri.


    AccessKey


    Alibaba Cloud hesabınızın veya RAM kullanıcınızın AccessKey çifti (AccessKey ID ve AccessKey secret). Daha fazla bilgi için bkz. AccessKey çifti oluşturma.


    httpserver


    Hizmeti başlatmak istediğiniz bağlantı noktası numarası.

    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 {
            // The KMS region, which must be the same as the video's region.
            String region = "";
            // The AccessKey pair for accessing KMS.
            // An AccessKey pair of an Alibaba Cloud account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M.
            // We strongly recommend against hard-coding the AccessKey ID and AccessKey secret in your project code. Doing so may lead to the leakage of the AccessKey pair and compromise the security of all resources in your account.
            // This example demonstrates how to authenticate API requests by reading the AccessKey pair from environment variables. Before running the sample code, configure the ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variables.
            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));
        }
        /**
         * Description:
         * 1. Receives a decryption request to get the ciphertext and user token.
         * 2. Calls the KMS decrypt operation to get the plaintext key.
         * 3. Returns the Base64-decoded plaintext key.
         */
        public class HlsDecryptHandler implements HttpHandler {
            /**
             * Handles the decryption request.
             * @param httpExchange
             * @throws IOException
             */
            public void handle(HttpExchange httpExchange) throws IOException {
                String requestMethod = httpExchange.getRequestMethod();
                if ("GET".equalsIgnoreCase(requestMethod)) {
                    // Verify the token's validity.
                    String token = getMtsHlsUriToken(httpExchange);
                    boolean validRe = validateToken(token);
                    if (!validRe) {
                        return;
                    }
                    // Get the ciphertext from the URL.
                    String ciphertext = getCiphertext(httpExchange);
                    if (null == ciphertext)
                        return;
                    // Decrypt the key from KMS and perform Base64 decoding.
                    byte[] key = decrypt(ciphertext);
                    // Set the header.
                    setHeader(httpExchange, key);
                    // Return the Base64-decoded key.
                    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);
            }
            /**
             * Calls the KMS decrypt operation and Base64-decodes the 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);
                    // Note: Base64 decoding is required.
                    return Base64.decodeBase64(plaintext);
                } catch (ClientException e) {
                    e.printStackTrace();
                    return null;
                }
            }
            /**
             * Gets the ciphertext parameter from the 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("Not Found CipherText Param");
                    return null;
                }
            }
              /**
             * Verifies the token's validity. This is required for M3U8 encryption and rewrite.
             * @param token
             * @return
             */
            private boolean validateToken(String token) {
                if (null == token || "".equals(token)) {
                    return false;
                }
                //TODO: Implement your token validation logic here.
                return true;
            }
            /**
             * Gets the token parameter. This is required for M3U8 encryption and rewrite.
             *
             * @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("Not Found MtsHlsUriToken Param");
                    return null;
                }
            }
        }
        /**
         * Starts the service.
         *
         * @throws IOException
         */
        private void serviceBootStrap() throws IOException {
            HttpServerProvider provider = HttpServerProvider.provider();
            // The listening port can be customized. The server can accept up to 30 concurrent requests.
            HttpServer httpserver = provider.createHttpServer(new InetSocketAddress(8099), 30);
            httpserver.createContext("/", new HlsDecryptHandler());
            httpserver.start();
            System.out.println("hls decrypt server started");
        }
        public static void main(String[] args) throws IOException {
            HlsDecryptServer server = new HlsDecryptServer();
            server.serviceBootStrap();
        }}
  2. Video oynatma URL'sini veya kimlik bilgisini alın.

    Oynatma kimlik bilgisini almak için GetVideoPlayAuth işlemini veya oynatma URL'sini almak için GetPlayInfo işlemini çağırın.

  3. Şifrelenmiş videoyu oynatın.

    HLS standart şifreleme tüm HLS oynatıcılarla uyumludur. Şifrelenmiş videoyu oynatmak için kendi geliştirdiğiniz bir oynatıcıyı veya ApsaraVideo Player'ı kullanabilirsiniz.

    ApsaraVideo Player kullanıyorsanız videoyu oynatmak için gereken belirteci ve kimlik doğrulama bilgilerini alın. Daha fazla bilgi için bkz. Şifrelenmiş videoyu oynatma. Farklı bir oynatıcı kullanıyorsanız oynatma mantığını uygulayın.

    Aşağıdaki bölümde ApsaraVideo Player'ın dahili oynatma süreci açıklanmaktadır:

    M3U8 yeniden yazma ile (önerilen)

    İş akışı

    • Oynatıcı, şifre çözme anahtarı URI'sini almak için M3U8 dosyasındaki EXT-X-KEY etiketini ayrıştırır. Bu URI, EncryptConfig içindeki DecryptKeyUri parametresinin değerine karşılık gelir.

    • Yetkisiz erişimi kısıtlamak için oynatıcı, şifre çözme uç noktasına yapılan istekte kimlik doğrulama bilgilerini (MtsHlsUriToken parametresinde iletilen) içermelidir.

    • Oynatıcı anahtarı almak için şifre çözme uç noktasına otomatik olarak istek gönderir, TS dosyalarının şifresini çözer ve ardından videoyu oynatır.

    Örnek

    • Oynatma URL'si https://demo.aliyundoc.com/encrypt-stream****-hd.m3u8 ise istek MtsHlsUriToken parametresini içermelidir.

    • Son istek URL'si: https://demo.aliyundoc.com/encrypt-stream****-hd.m3u8?MtsHlsUriToken=<token>

    • Şifre çözme URL'si: https://demo.aliyundoc.com?CipherText=ZjJmZGViNzUtZWY1Mi00Y2RlLTk3MTMtOT****

    • Son şifre çözme isteği URL'si: https://demo.aliyundoc.com?CipherText=ZjJmZGViNzUtZWY1Mi00Y2RlLTk3MTMtOT****&MtsHlsUriToken=<token>

M3U8 yeniden yazma olmadan

  1. Bir şifre çözme hizmeti kurun.

    Videoların şifresini çözmek için yerel bir HTTP hizmeti kurun.

    Veri anahtarının şifresini çözmek için DecryptKMSDataKey işlemini çağırın. Yanıttaki veri anahtarı olan PlainText, GenerateKMSDataKey işlemi tarafından döndürülen PlainText değerinin Base64 kodu çözülmüş halidir.

    Örnek:

    Java örnek kodunu genişletmek için tıklayın

    Aşağıdaki tabloda özelleştirebileceğiniz örnek koddaki parametreler açıklanmaktadır.


    Parametre


    Açıklama


    region


    Bölge kimliği. KMS hizmetinin bölgesi, ApsaraVideo VOD videonuzun depolandığı bölgeyle aynı olmalıdır. Örneğin, Çin (Şanghay) için bu parametreyi cn-shanghai olarak ayarlayın. Diğer bölge kimlikleri hakkında daha fazla bilgi için bkz. ApsaraVideo VOD bölge kimlikleri.


    AccessKey


    Alibaba Cloud hesabınızın veya RAM kullanıcınızın AccessKey çifti (AccessKey ID ve AccessKey secret). Daha fazla bilgi için bkz. AccessKey çifti oluşturma.


    httpserver


    Hizmeti başlatmak istediğiniz bağlantı noktası numarası.

    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 {
            // The KMS region, which must be the same as the video's region.
            String region = "cn-beijing";
            // The AccessKey pair for accessing KMS.
            // An AccessKey pair of an Alibaba Cloud account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M.
            // We strongly recommend against hard-coding the AccessKey ID and AccessKey secret in your project code. Doing so may lead to the leakage of the AccessKey pair and compromise the security of all resources in your account.
            // This example demonstrates how to authenticate API requests by reading the AccessKey pair from environment variables. Before running the sample code, configure the ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variables.
            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));
        }
        /**
         * Description:
         * 1. Receives a decryption request to get the ciphertext.
         * 2. Calls the KMS decrypt operation to get the plaintext key.
         * 3. Returns the Base64-decoded plaintext key.
         */
        public class HlsDecryptHandler implements HttpHandler {
            /**
             * Handles the decryption request.
             * @param httpExchange
             * @throws IOException
             */
            public void handle(HttpExchange httpExchange) throws IOException {
                String requestMethod = httpExchange.getRequestMethod();
                if ("GET".equalsIgnoreCase(requestMethod)) {
                    // Get the ciphertext from the URL.
                    String ciphertext = getCiphertext(httpExchange);
                    System.out.println(ciphertext);
                    if (null == ciphertext)
                        return;
                    // Decrypt the key from KMS and perform Base64 decoding.
                    byte[] key = decrypt(ciphertext);
                    // Set the header.
                    setHeader(httpExchange, key);
                    // Return the Base64-decoded key.
                    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);
            }
            /**
             * Calls the KMS decrypt operation and Base64-decodes the 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);
                    // Note: Base64 decoding is required.
                    return Base64.decodeBase64(plaintext);
                } catch (ClientException e) {
                    e.printStackTrace();
                    return null;
                }
            }
            /**
             * Gets the ciphertext parameter from the 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("Not Found CipherText Param");
                    return null;
                }
            }
        }
        /**
         * Starts the service.
         *
         * @throws IOException
         */
        private void serviceBootStrap() throws IOException {
            HttpServerProvider provider = HttpServerProvider.provider();
            // The listening port can be customized. The server can accept up to 30 concurrent requests.
            HttpServer httpserver = provider.createHttpServer(new InetSocketAddress(8099), 30);
            httpserver.createContext("/", new HlsDecryptHandler());
            httpserver.start();
            System.out.println("hls decrypt server started");
        }
        public static void main(String[] args) throws IOException {
            HlsDecryptServerNoToken server = new HlsDecryptServerNoToken();
            server.serviceBootStrap();
        }}
    
  2. Video oynatma URL'sini veya kimlik bilgisini alın.

    Oynatma kimlik bilgisini almak için GetVideoPlayAuth işlemini veya oynatma URL'sini almak için GetPlayInfo işlemini çağırın.

  3. Şifrelenmiş videoyu oynatın.

    HLS standart şifreleme tüm HLS oynatıcılarla uyumludur. Şifrelenmiş videoyu oynatmak için kendi geliştirdiğiniz bir oynatıcıyı veya ApsaraVideo Player'ı kullanabilirsiniz.

    ApsaraVideo Player kullanıyorsanız videoyu oynatmak için gereken belirteci ve kimlik doğrulama bilgilerini alın. Daha fazla bilgi için bkz. Şifrelenmiş videoyu oynatma. Farklı bir oynatıcı kullanıyorsanız oynatma mantığını uygulayın.

    Aşağıdaki bölümde ApsaraVideo Player'ın dahili oynatma süreci açıklanmaktadır:

    M3U8 yeniden yazma olmadan

    İş akışı

    • Oynatıcı, şifre çözme anahtarı URI'sini almak için M3U8 dosyasındaki EXT-X-KEY etiketini ayrıştırır; bu URI, EncryptConfig içindeki DecryptKeyUri parametresinin değerine karşılık gelir.

    • Oynatıcı anahtarı almak için şifre çözme uç noktasına otomatik olarak istek gönderir, TS dosyalarının şifresini çözer ve ardından videoyu oynatır.

    Örnek

    • Oynatma URL'si: https://demo.aliyundoc.com/encrypt-stream****-hd.m3u8

    • Son istek URL'si: https://demo.aliyundoc.com/encrypt-stream****-hd.m3u8

    • Şifre çözme URL'si: https://demo.aliyundoc.com?CipherText=ZjJmZGViNzUtZWY1Mi00Y2RlLTk3MTMtOT****

    • Son şifre çözme isteği URL'si: https://demo.aliyundoc.com?CipherText=ZjJmZGViNzUtZWY1Mi00Y2RlLTk3MTMtOT****

İlgili belgeler