Todos os produtos
Search
Central de documentação

ApsaraVideo VOD:Criptografia HLS

Última atualização: Jul 10, 2026

A criptografia HLS usa AES-128 e é compatível com todos os players HLS. Combinada ao gerenciamento de chaves e a um service de token, atende a cenários de alta segurança, como educação online e streaming de conteúdo exclusivo.

Como funciona

O ApsaraVideo VOD usa criptografia de envelope. O provedor de services utiliza o Key Management Service (KMS) da Alibaba Cloud para gerar uma chave de dados (DK) e uma chave de dados envelopada (EDK). A DK criptografa o vídeo, e a EDK é armazenada junto a ele. Durante a reprodução, o cliente obtém a DK do service de descriptografia para descriptografar o vídeo.

Para proteger a URL de descriptografia, ative a criptografia e reescrita de M3U8. Isso adiciona uma camada extra de proteção ao processo de acesso aos dados HLS. O parâmetro reescrito padrão é MtsHlsUriToken. Para saber como ativar esse recurso e entender seu funcionamento, consulte Criptografia e reescrita de M3U8.

Pré-requisitos

Conceitos principais

Conceito

Descrição

Resource Access Management (RAM)

Service da Alibaba Cloud que permite gerenciar identidades de usuários e controlar o acesso aos recursos. Para mais informações, consulte O que é RAM.

Key Management Service (KMS)

Plataforma completa da Alibaba Cloud para gerenciamento de chaves e criptografia de dados. Oferece uma solução simples, confiável, segura e compatível para proteger dados e gerenciar credenciais. Para mais informações, consulte O que é Key Management Service.

Chave de dados (DK)

Chave em texto simples usada para criptografar dados. Para mais informações, consulte Termos.

Chave de dados envelopada (EDK)

Chave de dados criptografada protegida por criptografia de envelope. Para mais informações, consulte Termos.

Fluxo de trabalho de criptografia e descriptografia

Fluxo de trabalho de upload e criptografia

视频安全-HLS标准加密3

Fluxo de trabalho de descriptografia e reprodução

Reescrita de M3U8 ativada (Recomendado)

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

Reescrita de M3U8 desativada

视频安全-HLS标准加密2

Criptografar um vídeo

  1. Faça o upload do vídeo e receba um callback.

    Para evitar que vídeos compatíveis com criptografia HLS sejam transcodificados automaticamente, use o grupo de modelos integrado No Transcoding ao fazer o upload para o ApsaraVideo VOD. Isso impede a transcodificação automática durante o upload.

    1. Para fazer upload de um vídeo pelo console do ApsaraVideo VOD, consulte Fazer upload de arquivos no console do ApsaraVideo VOD. Para fazer upload via API do lado do servidor, consulte Upload de mídia.

    2. Configure notificações de eventos para o ApsaraVideo VOD. Uma mensagem de callback do evento Upload de vídeo concluído indica que o vídeo foi carregado no ApsaraVideo VOD. Para saber como configurar notificações de eventos, consulte Notificações de eventos.

  2. Configure um service de criptografia.

    1. Crie uma chave de service.

      A chave de service é a chave primária de criptografia no KMS e deve ser usada para gerar chaves para criptografia HLS. Se você não criar uma chave de service, a operação GenerateKMSDataKey retornará um erro.

      1. No canto superior esquerdo da página, clique em no ID da região para alternar para a região onde deseja criar a chave de service.

        Nota

        A chave de service deve estar na mesma região do servidor de origem do vídeo. Por exemplo, se o vídeo estiver armazenado em China (Shanghai), a chave de service também deve ser criada na região China (Shanghai).

        As regiões disponíveis são China (Shanghai), China (Beijing), China (Shenzhen), Japan (Tokyo), Singapore, Indonesia (Jakarta), India (Mumbai) e Germany (Frankfurt).

      2. Faça login no console do ApsaraVideo VOD. No painel de navegação à esquerda, escolha Configuration Management > Media Processing > HLS Standard Encryption.

      3. Na página HLS Encryption, clique em Create Service Key.

        Após a criação da chave de service, uma mensagem de confirmação será exibida. Em seguida, visualize a chave na seção Key Information.

        Nota

        Se uma mensagem de sucesso aparecer, mas a chave não estiver visível, a causa pode ser a ausência de uma função vinculada ao service. Reautorize o ApsaraVideo VOD para restaurar a função e atualize a página para visualizar a chave de service.

    2. Chame uma operação de API para gerar uma chave de dados (DK).

      Chame a operação GenerateKMSDataKey para gerar uma chave de dados (DK) e uma chave de dados envelopada (EDK). Não é necessário passar nenhum parâmetro. Após uma chamada bem-sucedida, o campo Plaintext na resposta contém a DK, e o campo CiphertextBlob contém a EDK no formato AES-128. Armazene em cache o valor de CiphertextBlob para o job de transcodificação com criptografia HLS.

  3. Crie um grupo de modelos de transcodificação para criptografia HLS.

    O processo de criptografia HLS requer dois grupos de modelos de transcodificação: o grupo integrado No Transcoding e um grupo personalizado para criptografia HLS. Para criar um grupo de modelos de transcodificação personalizado, siga estas etapas:

    1. Faça login no console do ApsaraVideo VOD. No painel de navegação à esquerda, escolha Configuration Management > Media Processing > Transcoding Template Groups.

    2. Na página Transcoding Template Groups, crie um grupo de modelos de transcodificação para criptografia HLS.

      Defina Encapsulation Format como hls. Na seção Advanced Parameters, ative Video Encryption e selecione a opção Alibaba Cloud Encryption. Configure outros parâmetros conforme necessário. Para mais informações sobre os parâmetros, consulte Modelos de transcodificação.

    3. Após criar o grupo de modelos, localize o novo grupo na lista da página Transcoding Template Groups e anote seu ID. Esse ID do grupo de modelos é obrigatório para a configuração de criptografia.

  4. Envie um job de transcodificação com criptografia HLS.

    1. Chame a operação SubmitTranscodeJobs para enviar um job de transcodificação com criptografia HLS.

      Código de exemplo em Java

      No código de exemplo em Java abaixo, altere os seguintes parâmetros conforme suas necessidades:

      Parâmetro

      Valor

      request.setTemplateGroupId("")

      O ID do grupo de modelos de transcodificação para criptografia HLS criado na Etapa 3.

      request.setVideoId("")

      O ID do vídeo enviado na Etapa 1.

      encryptConfig.put("CipherText","")

      O valor de CiphertextBlob retornado na Etapa 2.

      encryptConfig.put("DecryptKeyUri","")

      A URI da chave. A URI é criada concatenando a URL do service de descriptografia e o valor de CiphertextBlob. Por exemplo, se o service for executado localmente na porta 8099, a URI da chave será:

      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. Se você configurou notificações de eventos, uma mensagem de callback do evento Single Definition Transcoding Complete ou Transcode complete indica que o job de transcodificação foi concluído.

  5. Verifique o resultado da criptografia HLS.

    Após a conclusão do job de transcodificação, use um dos métodos a seguir para verificar a criptografia.

    • Método 1: Faça login no console do ApsaraVideo VOD. Acesse a página de detalhes do arquivo de Audio/Video e clique em na aba Video URL. Na lista de URLs de vídeo, verifique na coluna de formato se há uma tag HLS Encryption no arquivo de saída M3U8. A presença dessa tag confirma que a criptografia foi bem-sucedida.

    • Método 2: Copie a URL do arquivo M3U8 que possui a tag HLS Standard Encryption. Execute o comando curl -v "URL do arquivo M3U8" para recuperar o conteúdo do M3U8. Verifique no conteúdo as seguintes informações-chave: URI="<the decryption URI that you provided as the DecryptKeyUri parameter value>". Se essa informação estiver presente, a criptografia foi bem-sucedida.

    • Método 3: Chame a operação GetTranscodeTask e passe o valor do parâmetro JobId retornado na Etapa 4. A criptografia é considerada bem-sucedida se o valor de TranscodeTemplateId na resposta corresponder ao ID do grupo de modelos de transcodificação criado na Etapa 3 e TranscodeJobStatus for TranscodeSuccess.

Criptografia e reescrita HLS (M3U8) (Recomendado)

Com a criptografia e reescrita de M3U8 ativadas, o sistema adiciona automaticamente parâmetros de criptografia, incluindo algoritmo, URI da chave e parâmetros de autenticação, à tag #EXT-X-KEY na Media Playlist HLS (arquivo M3U8). Quando um cliente analisa o arquivo M3U8 reescrito, ele usa a URI da chave com parâmetros de autenticação para solicitar a chave de descriptografia e, em seguida, descriptografa os segmentos de fluxo de transporte (TS) com o algoritmo especificado.

Etapa 1: Ativar passagem de parâmetros para criptografia HLS

No console do ApsaraVideo VOD, ative Parameter Pass-through for HLS Encryption.

Ao ativar Parameter Pass-through for HLS Encryption, o ApsaraVideo VOD reescreve o arquivo M3U8, modificando a URI na tag #EXT-X-KEY ao anexar parâmetros da solicitação do cliente. O nome do parâmetro padrão é MtsHlsUriToken.

Pré-requisitos

Configure o compartilhamento de recursos de origem cruzada (CORS). Para mais informações, consulte Configurar compartilhamento de recursos de origem cruzada.

Importante

Este recurso não está disponível na Alibaba Cloud Gov Cloud.

Procedimento

  1. Faça login no console do ApsaraVideo VOD.

  2. No painel de navegação à esquerda, clique em Configuration Management.

  3. Clique em CDN Configuration > Domain Names para acessar a página Domain Names.

  4. Localize o nome de domínio que deseja gerenciar e clique em configure na coluna Actions.

  5. Na página de configuração do domínio, clique em Video Related no painel de navegação à esquerda.

  6. Na seção encrypted playback, ative a chave Parameter Pass-through for HLS Encryption. Por padrão, essa chave está desativada e o nome do parâmetro é MtsHlsUriToken.

Nota
  • Ao ativar este recurso, o ApsaraVideo VOD lida com a autenticação reescrevendo o parâmetro de token. O parâmetro reescrito é MtsHlsUriToken e seu valor é test. Durante a reprodução descriptografada, o ponto de presença (POP) anexa MtsHlsUriToken=test à URI na tag #EXT-X-KEY do arquivo M3U8.

Etapa 2: Enviar solicitação com MtsHlsUriToken

Para acessar o arquivo M3U8, o cliente envia uma solicitação que inclui o parâmetro MtsHlsUriToken a um ponto de presença (POP).

É necessário criar um service de token para gerar e emitir o MtsHlsUriToken para os usuários.

O código a seguir gera o MtsHlsUriToken. Modifique os parâmetros abaixo conforme os requisitos do seu negócio:

Código de exemplo em Java

Parâmetro

Descrição

ENCRYPT_KEY

A chave de criptografia. Uma string personalizada de 16, 24 ou 32 caracteres.

INIT_VECTOR

O deslocamento de criptografia. Uma string personalizada de 16 caracteres que não pode conter caracteres especiais.

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

O código de exemplo acima serve apenas como referência. Ele não envolve nenhum SDK ou código de service. Configure-o e ajuste-o conforme os requisitos do seu negócio.

Etapa 3: Descriptografar e reproduzir o arquivo

Ao receber uma solicitação do cliente, o ponto de presença (POP) a autentica. Se a autenticação for bem-sucedida, o POP descriptografa e reproduz o arquivo.

Se o parâmetro MtsHlsUriToken gerado na Etapa 2 tiver o valor test, o POP anexará MtsHlsUriToken=test à URI na tag #EXT-X-KEY do arquivo M3U8 durante a reprodução descriptografada.

Implemente a lógica de autenticação. Para referência, consulte o código de exemplo do service de descriptografia para criptografia e reescrita de M3U8 em Reproduzir vídeos.

Reproduzir vídeo

Com reescrita de M3U8 (recomendado)

  1. Configure um service de descriptografia.

    Configure um service HTTP local para descriptografar vídeos.

    Chame a operação DecryptKMSDataKey para descriptografar a chave de dados. A chave de dados na resposta, PlainText, é a versão decodificada em Base64 do valor PlainText retornado pela operação GenerateKMSDataKey.

    Para adicionar uma camada extra de segurança verificando as URLs de descriptografia, ative a criptografia e reescrita de M3U8. Esse recurso adiciona um token à URL de solicitação da chave. O nome do parâmetro padrão é MtsHlsUriToken. A implementação do seu service de descriptografia depende da ativação desse recurso.

    Clique para expandir o código de exemplo em Java

    A tabela a seguir descreve os parâmetros no código de exemplo que podem ser personalizados.

    Parâmetro

    Descrição

    region

    O ID da região. A região do service KMS deve ser a mesma onde o vídeo do ApsaraVideo VOD está armazenado. Por exemplo, para China (Shanghai), defina este parâmetro como cn-shanghai. Para mais informações sobre outros IDs de região, consulte IDs de região do ApsaraVideo VOD.

    AccessKey

    O par de AccessKey (AccessKey ID e AccessKey secret) da sua conta Alibaba Cloud ou usuário RAM. Para mais informações, consulte Criar um par de AccessKey.

    httpserver

    O número da porta na qual deseja iniciar o 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. Obtenha a URL ou credencial de reprodução do vídeo.

    Chame a operação GetVideoPlayAuth para obter a credencial de reprodução ou chame a operação GetPlayInfo para obter a URL de reprodução.

  3. Reproduza o vídeo criptografado.

    A criptografia padrão HLS é compatível com todos os players HLS. Use um player desenvolvido internamente ou o ApsaraVideo Player para reproduzir o vídeo criptografado.

    Se utilizar o ApsaraVideo Player, obtenha o token e as informações de autenticação necessários para reproduzir o vídeo. Para mais informações, consulte Reproduzir um vídeo criptografado. Caso utilize outro player, implemente a lógica de reprodução.

    A seção a seguir descreve o processo interno de reprodução do ApsaraVideo Player:

    Com reescrita de M3U8 (recomendado)

    Fluxo de trabalho

    • O player analisa a tag EXT-X-KEY no arquivo M3U8 para obter a URI da chave de descriptografia. Essa URI corresponde ao valor do parâmetro DecryptKeyUri em EncryptConfig.

    • Para restringir acessos não autorizados, o player deve incluir informações de autenticação (passadas no parâmetro MtsHlsUriToken) na solicitação ao endpoint de descriptografia.

    • O player solicita automaticamente a chave ao endpoint de descriptografia, descriptografa os arquivos TS e, em seguida, reproduz o vídeo.

    Exemplo

    • Se a URL de reprodução for https://demo.aliyundoc.com/encrypt-stream****-hd.m3u8, a solicitação deve incluir o parâmetro MtsHlsUriToken.

    • URL final da solicitação: https://demo.aliyundoc.com/encrypt-stream****-hd.m3u8?MtsHlsUriToken=<token>

    • URL de descriptografia: https://demo.aliyundoc.com?CipherText=ZjJmZGViNzUtZWY1Mi00Y2RlLTk3MTMtOT****

    • URL final da solicitação de descriptografia: https://demo.aliyundoc.com?CipherText=ZjJmZGViNzUtZWY1Mi00Y2RlLTk3MTMtOT****&MtsHlsUriToken=<token>

Sem reescrita de M3U8

  1. Configure um service de descriptografia.

    Configure um service HTTP local para descriptografar vídeos.

    Chame a operação DecryptKMSDataKey para descriptografar a chave de dados. A chave de dados na resposta, PlainText, é a versão decodificada em Base64 do valor PlainText retornado pela operação GenerateKMSDataKey.

    Por exemplo:

    Clique para expandir o código de exemplo em Java

    A tabela a seguir descreve os parâmetros no código de exemplo que podem ser personalizados.

    Parâmetro

    Descrição

    region

    O ID da região. A região do service KMS deve ser a mesma onde o vídeo do ApsaraVideo VOD está armazenado. Por exemplo, para China (Shanghai), defina este parâmetro como cn-shanghai. Para mais informações sobre outros IDs de região, consulte IDs de região do ApsaraVideo VOD.

    AccessKey

    O par de AccessKey (AccessKey ID e AccessKey secret) da sua conta Alibaba Cloud ou usuário RAM. Para mais informações, consulte Criar um par de AccessKey.

    httpserver

    O número da porta na qual deseja iniciar o 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. Obtenha a URL ou credencial de reprodução do vídeo.

    Chame a operação GetVideoPlayAuth para obter a credencial de reprodução ou chame a operação GetPlayInfo para obter a URL de reprodução.

  3. Reproduza o vídeo criptografado.

    A criptografia padrão HLS é compatível com todos os players HLS. Use um player desenvolvido internamente ou o ApsaraVideo Player para reproduzir o vídeo criptografado.

    Se utilizar o ApsaraVideo Player, obtenha o token e as informações de autenticação necessários para reproduzir o vídeo. Para mais informações, consulte Reproduzir um vídeo criptografado. Caso utilize outro player, implemente a lógica de reprodução.

    A seção a seguir descreve o processo interno de reprodução do ApsaraVideo Player:

    Sem reescrita de M3U8

    Fluxo de trabalho

    • O player analisa a tag EXT-X-KEY no arquivo M3U8 para obter a URI da chave de descriptografia, que corresponde ao valor do parâmetro DecryptKeyUri em EncryptConfig.

    • O player solicita automaticamente a chave ao endpoint de descriptografia, descriptografa os arquivos TS e, em seguida, reproduz o vídeo.

    Exemplo

    • URL de reprodução: https://demo.aliyundoc.com/encrypt-stream****-hd.m3u8

    • URL final da solicitação: https://demo.aliyundoc.com/encrypt-stream****-hd.m3u8

    • URL de descriptografia: https://demo.aliyundoc.com?CipherText=ZjJmZGViNzUtZWY1Mi00Y2RlLTk3MTMtOT****

    • URL final da solicitação de descriptografia: https://demo.aliyundoc.com?CipherText=ZjJmZGViNzUtZWY1Mi00Y2RlLTk3MTMtOT****

Documentação relacionada