Tous les produits
Search
Centre de documentation

ApsaraVideo VOD:Chiffrement HLS

Dernière mise à jour :Aug 10, 2026

Le chiffrement HLS utilise l'algorithme AES-128 et est compatible avec tous les lecteurs HLS. Associé à la gestion des clés et à un service de jetons, il convient aux scénarios nécessitant un niveau de sécurité élevé, tels que l'éducation en ligne et la diffusion de contenu exclusif.

Fonctionnement

ApsaraVideo VOD utilise le chiffrement par enveloppe. Le fournisseur de services utilise Alibaba Cloud Key Management Service (KMS) pour générer une clé de données (DK) et une clé de données sous enveloppe (EDK). La DK sert à chiffrer la vidéo, tandis que l'EDK est stockée conjointement avec celle-ci. Lors de la lecture, le client récupère la DK auprès du service de déchiffrement afin de déchiffrer la vidéo.

Pour sécuriser l'URL de déchiffrement, activez le chiffrement et la réécriture M3U8, qui ajoutent une couche de protection supplémentaire au processus d'accès aux données HLS. Le paramètre réécrit par défaut est MtsHlsUriToken. Pour savoir comment activer cette fonctionnalité et comprendre son fonctionnement, consultez la rubrique Chiffrement et réécriture M3U8.

Prérequis

  • Le chiffrement HLS est un service gratuit. Toutefois, cette fonctionnalité nécessite le transcodage des vidéos, ce qui engendre des frais. Pour plus d'informations sur la tarification, consultez la rubrique Facturation du transcodage multimédia.

  • Vous avez activé ApsaraVideo VOD. Pour obtenir des instructions, consultez la rubrique Activation d'ApsaraVideo VOD.

  • Vous avez autorisé ApsaraVideo VOD à accéder à votre service Key Management Service (KMS). Vous pouvez accorder les autorisations requises sur la page Autorisation d'accès aux ressources cloud.

  • Vous avez ajouté un nom de domaine accéléré dans ApsaraVideo VOD. Pour obtenir des instructions, consultez la rubrique Ajout d'un nom de domaine accéléré.

  • Vous avez installé le SDK côté serveur requis. Pour plus d'informations, consultez la rubrique SDK côté serveur. Cette rubrique utilise le SDK pour Java à titre d'exemple.

Concepts clés

Concept

Description

Resource Access Management (RAM)

Un service Alibaba Cloud qui vous permet de gérer les identités des utilisateurs et de contrôler l'accès à vos ressources. Pour plus d'informations, consultez la rubrique Présentation de RAM.

Key Management Service (KMS)

Une plateforme Alibaba Cloud tout-en-un dédiée à la gestion des clés et au chiffrement des données. Elle offre une solution simple, fiable, sécurisée et conforme pour protéger vos données et gérer vos identifiants. Pour plus d'informations, consultez la rubrique Présentation de Key Management Service.

Clé de données (DK)

Une clé en texte clair utilisée pour chiffrer les données. Pour plus d'informations, consultez la rubrique Termes.

Clé de données sous enveloppe (EDK)

Une clé de données chiffrée protégée par le chiffrement par enveloppe. Pour plus d'informations, consultez la rubrique Termes.

Flux de travail de chiffrement et de déchiffrement

Flux de travail de chargement et de chiffrement

视频安全-HLS标准加密3

Flux de travail de déchiffrement et de lecture

Réécriture M3U8 activée (recommandé)

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

Réécriture M3U8 désactivée

视频安全-HLS标准加密2

Chiffrer une vidéo

  1. Chargez votre vidéo et recevez un rappel.

    Pour empêcher le transcodage automatique des vidéos compatibles avec le chiffrement HLS, vous devez utiliser le groupe de modèles intégré No Transcoding lors du chargement des vidéos dans ApsaraVideo VOD. Cela évite tout transcodage automatique pendant le chargement.

    1. Pour charger une vidéo via la console ApsaraVideo VOD, consultez la rubrique Chargement de fichiers dans la console ApsaraVideo VOD. Pour charger une vidéo via une API côté serveur, consultez la rubrique Chargement de médias.

    2. Configurez les notifications d'événements pour ApsaraVideo VOD. Un message de rappel pour l'événement Video upload completed indique que la vidéo a été chargée dans ApsaraVideo VOD. Pour savoir comment configurer les notifications d'événements, consultez la rubrique Notifications d'événements.

  2. Configurez un service de chiffrement.

    1. Créez une clé de service.

      Une clé de service constitue la clé de chiffrement principale dans KMS et doit être utilisée pour générer des clés pour le chiffrement HLS. Si vous ne créez pas de clé de service, l'opération GenerateKMSDataKey renvoie une erreur.

      1. Dans le coin supérieur gauche de la page, cliquez sur l'ID de région pour basculer vers la région où vous souhaitez créer la clé de service.

        Remarque

        La clé de service doit se trouver dans la même région que le serveur d'origine de votre vidéo. Par exemple, si votre vidéo est stockée en Chine (Shanghai), la clé de service doit également être créée dans la région Chine (Shanghai).

        Les régions disponibles sont Chine (Shanghai), Chine (Pékin), Chine (Shenzhen), Japon (Tokyo), Singapour, Indonésie (Jakarta), Inde (Mumbai) et Allemagne (Francfort).

      2. Connectez-vous à la console ApsaraVideo VOD. Dans le volet de navigation de gauche, choisissez Configuration Management > Media Processing > HLS Standard Encryption.

      3. Sur la page HLS Encryption, cliquez sur Create Service Key.

        Une fois la clé de service créée, un message de confirmation s'affiche. Vous pouvez ensuite afficher la clé dans la section Key Information.

        Remarque

        Si un message de réussite s'affiche mais que vous ne parvenez pas à voir la clé, cela peut être dû à l'absence d'un rôle lié au service. Vous pouvez réautoriser ApsaraVideo VOD pour restaurer le rôle, puis actualiser la page pour afficher la clé de service.

    2. Appelez une opération d'API pour générer une clé de données (DK).

      Appelez l'opération GenerateKMSDataKey pour générer une clé de données (DK) et une clé de données sous enveloppe (EDK). Aucun paramètre n'est requis. Après un appel réussi, le champ Plaintext de la réponse contient la DK, et le champ CiphertextBlob contient l'EDK au format AES-128. Mettez en cache la valeur CiphertextBlob pour la tâche de transcodage de chiffrement HLS.

  3. Créez un groupe de modèles de transcodage pour le chiffrement HLS.

    Le processus de chiffrement HLS nécessite deux groupes de modèles de transcodage : le groupe de modèles intégré No Transcoding et un groupe de modèles de transcodage personnalisé pour le chiffrement HLS. Pour créer un groupe de modèles de transcodage personnalisé, procédez comme suit :

    1. Connectez-vous à la console ApsaraVideo VOD. Dans le volet de navigation de gauche, choisissez Configuration Management > Media Processing > Transcoding Template Groups.

    2. Sur la page Transcoding Template Groups, créez un groupe de modèles de transcodage pour le chiffrement HLS.

      Définissez le paramètre Encapsulation Format sur hls. Dans la section Advanced Parameters, activez l'option Video Encryption et sélectionnez l'option Alibaba Cloud Encryption. Configurez les autres paramètres selon vos besoins. Pour plus d'informations sur les paramètres, consultez la rubrique Modèles de transcodage.

    3. Une fois le groupe de modèles créé, repérez-le dans la liste sur la page Transcoding Template Groups et notez son ID. Cet ID de groupe de modèles est requis pour la configuration du chiffrement.

  4. Soumettez une tâche de transcodage de chiffrement HLS.

    1. Appelez l'opération SubmitTranscodeJobs pour soumettre une tâche de transcodage de chiffrement HLS.

      Exemple de code Java

      Dans l'exemple de code Java suivant, modifiez les paramètres suivants en fonction de vos besoins :

      Paramètre

      Valeur

      request.setTemplateGroupId("")

      L'ID du groupe de modèles de transcodage pour le chiffrement HLS que vous avez créé à l'étape 3.

      request.setVideoId("")

      L'ID de la vidéo que vous avez chargée à l'étape 1.

      encryptConfig.put("CipherText","")

      La valeur CiphertextBlob renvoyée à l'étape 2.

      encryptConfig.put("DecryptKeyUri","")

      L'URI de la clé. L'URI est créé en concaténant l'URL du service de déchiffrement et la valeur CiphertextBlob. Par exemple, si votre service s'exécute localement sur le port 8099, l'URI de la clé est le suivant :

      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. Si vous avez configuré des notifications d'événements, un message de rappel pour l'événement Single Definition Transcoding Complete ou Transcode complete indique que la tâche de transcodage est terminée.

  5. Vérifiez le résultat du chiffrement HLS.

    Une fois la tâche de transcodage terminée, utilisez l'une des méthodes suivantes pour vérifier le chiffrement.

    • Méthode 1 : Connectez-vous à la console ApsaraVideo VOD. Accédez à la page de détails du fichier Audio/Video et cliquez sur l'onglet Video URL. Dans la liste des URL vidéo, vérifiez la présence d'une balise HLS Encryption dans la colonne de format du fichier de sortie M3U8. La présence de cette balise confirme que le chiffrement a réussi.

    • Méthode 2 : Copiez l'URL du fichier M3U8 portant la balise HLS Standard Encryption. Exécutez la commande curl -v "URL du fichier M3U8" pour récupérer le contenu M3U8. Vérifiez la présence des informations de clé suivantes dans le contenu : URI="<l'URI de déchiffrement que vous avez fourni comme valeur du paramètre DecryptKeyUri>". Si ces informations sont présentes, le chiffrement a réussi.

    • Méthode 3 : Appelez l'opération GetTranscodeTask et transmettez la valeur du paramètre JobId renvoyée à l'étape 4. Le chiffrement est réussi si la valeur de TranscodeTemplateId dans la réponse correspond à l'ID du groupe de modèles de transcodage que vous avez créé à l'étape 3 et si TranscodeJobStatus est défini sur TranscodeSuccess.

Chiffrement et réécriture HLS (M3U8) (recommandé)

Lorsque le chiffrement et la réécriture M3U8 sont activés, le système ajoute automatiquement des paramètres de chiffrement, notamment l'algorithme, l'URI de la clé et les paramètres d'authentification, à la balise #EXT-X-KEY de la liste de lecture multimédia HLS (fichier M3U8). Lorsqu'un client analyse le fichier M3U8 réécrit, il utilise l'URI de la clé avec les paramètres d'authentification pour demander la clé de déchiffrement, puis déchiffre les segments de flux de transport (TS) à l'aide de l'algorithme spécifié.

Étape 1 : Activer le transfert de paramètres pour le chiffrement HLS

Dans la console ApsaraVideo VOD, activez l'option Parameter Pass-through for HLS Encryption.

Après avoir activé l'option Parameter Pass-through for HLS Encryption, ApsaraVideo VOD réécrit le fichier M3U8 en modifiant l'URI de la balise #EXT-X-KEY pour y ajouter les paramètres issus de la demande du client. Le nom de paramètre par défaut est MtsHlsUriToken.

Prérequis

Vous avez configuré le partage de ressources cross-origin (CORS). Pour plus d'informations, consultez la rubrique Configuration du partage de ressources cross-origin.

Important

Cette fonctionnalité n'est pas disponible dans Alibaba Cloud Gov Cloud.

Procédure

  1. Connectez-vous à la console ApsaraVideo VOD.

  2. Dans le volet de navigation de gauche, cliquez sur Configuration Management.

  3. Cliquez sur CDN Configuration > Domain Names pour accéder à la page Domain Names.

  4. Repérez le nom de domaine que vous souhaitez gérer et cliquez sur configure dans la colonne Actions.

  5. Sur la page de configuration du domaine, cliquez sur Video Related dans le volet de navigation de gauche.

  6. Dans la section encrypted playback, activez l'interrupteur Parameter Pass-through for HLS Encryption. Par défaut, cet interrupteur est désactivé et le nom du paramètre est MtsHlsUriToken.

Remarque
  • Après avoir activé cette fonctionnalité, ApsaraVideo VOD gère l'authentification en réécrivant le paramètre de jeton. Le paramètre réécrit est MtsHlsUriToken et sa valeur est test. Lors de la lecture déchiffrée, le point de présence (POP) ajoute MtsHlsUriToken=test à l'URI de la balise #EXT-X-KEY du fichier M3U8.

Étape 2 : Envoyer une demande avec MtsHlsUriToken

Pour accéder au fichier M3U8, le client envoie une demande incluant le paramètre MtsHlsUriToken à un point de présence (POP).

Vous devez mettre en place un service de jetons pour générer et délivrer le MtsHlsUriToken aux utilisateurs.

Le code suivant génère le MtsHlsUriToken. Vous devez modifier les paramètres suivants en fonction de vos besoins métier :

Exemple de code Java

Paramètre

Description

ENCRYPT_KEY

La clé de chiffrement. Une chaîne personnalisée de 16, 24 ou 32 caractères.

INIT_VECTOR

Le vecteur d'initialisation du chiffrement. Une chaîne personnalisée de 16 caractères qui ne doit pas contenir de caractères spéciaux.

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;
    }}
                        
Remarque

L'exemple de code précédent est fourni à titre indicatif uniquement. Il n'implique aucun SDK ni code de service. Vous devez le configurer et l'ajuster en fonction de vos besoins métier.

Étape 3 : Déchiffrer et lire le fichier

Lorsqu'il reçoit une demande du client, le point de présence (POP) l'authentifie. Si l'authentification réussit, le POP déchiffre et lit le fichier.

Si le paramètre MtsHlsUriToken généré à l'étape 2 a pour valeur test, le POP ajoute MtsHlsUriToken=test à l'URI de la balise #EXT-X-KEY du fichier M3U8 lors de la lecture déchiffrée.

Vous devez implémenter la logique d'authentification. À titre de référence, consultez l'exemple de code du service de déchiffrement pour le chiffrement et la réécriture M3U8 dans la rubrique Lecture de vidéos.

Lire une vidéo

Avec réécriture M3U8 (recommandé)

  1. Configurez un service de déchiffrement.

    Configurez un service HTTP local pour déchiffrer les vidéos.

    Appelez l'opération DecryptKMSDataKey pour déchiffrer la clé de données. La clé de données dans la réponse, PlainText, correspond à la version décodée en Base64 de la valeur PlainText renvoyée par l'opération GenerateKMSDataKey.

    Pour ajouter une couche de sécurité supplémentaire en vérifiant les URL de déchiffrement, activez le chiffrement et la réécriture M3U8. Cette fonctionnalité ajoute un jeton à l'URL de demande de clé. Le nom de paramètre par défaut est MtsHlsUriToken. L'implémentation de votre service de déchiffrement dépend de l'activation ou non de cette fonctionnalité.

    Cliquez pour développer l'exemple de code Java

    Le tableau suivant décrit les paramètres de l'exemple de code que vous pouvez personnaliser.

    Paramètre

    Description

    region

    L'ID de région. La région du service KMS doit être identique à celle où votre vidéo ApsaraVideo VOD est stockée. Par exemple, pour la Chine (Shanghai), définissez ce paramètre sur cn-shanghai. Pour plus d'informations sur les autres ID de région, consultez la rubrique ID de région ApsaraVideo VOD.

    AccessKey

    La paire AccessKey (AccessKey ID et AccessKey secret) de votre compte Alibaba Cloud ou utilisateur RAM. Pour plus d'informations, consultez la rubrique Création d'une paire AccessKey.

    httpserver

    Le numéro de port sur lequel vous souhaitez démarrer le service.

    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. Obtenez l'URL de lecture de la vidéo ou les identifiants.

    Appelez l'opération GetVideoPlayAuth pour obtenir les identifiants de lecture, ou appelez l'opération GetPlayInfo pour obtenir l'URL de lecture.

  3. Lisez la vidéo chiffrée.

    Le chiffrement standard HLS est compatible avec tous les lecteurs HLS. Vous pouvez utiliser un lecteur développé en interne ou ApsaraVideo Player pour lire la vidéo chiffrée.

    Si vous utilisez ApsaraVideo Player, obtenez le jeton et les informations d'authentification nécessaires pour lire la vidéo. Pour plus d'informations, consultez la rubrique Lecture d'une vidéo chiffrée. Si vous utilisez un autre lecteur, implémentez la logique de lecture.

    La section suivante décrit le processus de lecture interne d'ApsaraVideo Player :

    Avec réécriture M3U8 (recommandé)

    Flux de travail

    • Le lecteur analyse la balise EXT-X-KEY du fichier M3U8 pour obtenir l'URI de la clé de déchiffrement. Cet URI correspond à la valeur du paramètre DecryptKeyUri dans EncryptConfig.

    • Pour restreindre l'accès non autorisé, le lecteur doit inclure des informations d'authentification (transmises dans le paramètre MtsHlsUriToken) dans la demande adressée au endpoint de déchiffrement.

    • Le lecteur demande automatiquement au endpoint de déchiffrement d'obtenir la clé, déchiffre les fichiers TS, puis lit la vidéo.

    Exemple

    • Si l'URL de lecture est https://demo.aliyundoc.com/encrypt-stream****-hd.m3u8, la demande doit inclure le paramètre MtsHlsUriToken.

    • URL de demande finale : https://demo.aliyundoc.com/encrypt-stream****-hd.m3u8?MtsHlsUriToken=<jeton>

    • URL de déchiffrement : https://demo.aliyundoc.com?CipherText=ZjJmZGViNzUtZWY1Mi00Y2RlLTk3MTMtOT****

    • URL de demande de déchiffrement finale : https://demo.aliyundoc.com?CipherText=ZjJmZGViNzUtZWY1Mi00Y2RlLTk3MTMtOT****&MtsHlsUriToken=<jeton>

Sans réécriture M3U8

  1. Configurez un service de déchiffrement.

    Configurez un service HTTP local pour déchiffrer les vidéos.

    Appelez l'opération DecryptKMSDataKey pour déchiffrer la clé de données. La clé de données dans la réponse, PlainText, correspond à la version décodée en Base64 de la valeur PlainText renvoyée par l'opération GenerateKMSDataKey.

    Par exemple :

    Cliquez pour développer l'exemple de code Java

    Le tableau suivant décrit les paramètres de l'exemple de code que vous pouvez personnaliser.

    Paramètre

    Description

    region

    L'ID de région. La région du service KMS doit être identique à celle où votre vidéo ApsaraVideo VOD est stockée. Par exemple, pour la Chine (Shanghai), définissez ce paramètre sur cn-shanghai. Pour plus d'informations sur les autres ID de région, consultez la rubrique ID de région ApsaraVideo VOD.

    AccessKey

    La paire AccessKey (AccessKey ID et AccessKey secret) de votre compte Alibaba Cloud ou utilisateur RAM. Pour plus d'informations, consultez la rubrique Création d'une paire AccessKey.

    httpserver

    Le numéro de port sur lequel vous souhaitez démarrer le service.

    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. Obtenez l'URL de lecture de la vidéo ou les identifiants.

    Appelez l'opération GetVideoPlayAuth pour obtenir les identifiants de lecture, ou appelez l'opération GetPlayInfo pour obtenir l'URL de lecture.

  3. Lisez la vidéo chiffrée.

    Le chiffrement standard HLS est compatible avec tous les lecteurs HLS. Vous pouvez utiliser un lecteur développé en interne ou ApsaraVideo Player pour lire la vidéo chiffrée.

    Si vous utilisez ApsaraVideo Player, obtenez le jeton et les informations d'authentification nécessaires pour lire la vidéo. Pour plus d'informations, consultez la rubrique Lecture d'une vidéo chiffrée. Si vous utilisez un autre lecteur, implémentez la logique de lecture.

    La section suivante décrit le processus de lecture interne d'ApsaraVideo Player :

    Sans réécriture M3U8

    Flux de travail

    • Le lecteur analyse la balise EXT-X-KEY du fichier M3U8 pour obtenir l'URI de la clé de déchiffrement, qui correspond à la valeur du paramètre DecryptKeyUri dans EncryptConfig.

    • Le lecteur demande automatiquement au endpoint de déchiffrement d'obtenir la clé, déchiffre les fichiers TS, puis lit la vidéo.

    Exemple

    • URL de lecture : https://demo.aliyundoc.com/encrypt-stream****-hd.m3u8

    • URL de demande finale : https://demo.aliyundoc.com/encrypt-stream****-hd.m3u8

    • URL de déchiffrement : https://demo.aliyundoc.com?CipherText=ZjJmZGViNzUtZWY1Mi00Y2RlLTk3MTMtOT****

    • URL de demande de déchiffrement finale : https://demo.aliyundoc.com?CipherText=ZjJmZGViNzUtZWY1Mi00Y2RlLTk3MTMtOT****

Documentation connexe