すべてのプロダクト
Search
ドキュメントセンター

ApsaraVideo Media Processing:HLS 暗号化

最終更新日:May 09, 2025

動画暗号化機能を使用すると、動画コンテンツに対して詳細なセキュリティ処理を実行し、動画データが不正に取得および送信されるのを防ぐことができます。この機能は、オンライン教育や金融など、セキュリティレベルの高いシナリオで動画の漏洩やホットリンクを防ぐために広く使用されています。ApsaraVideo Media Processing(MPS)は、Alibaba Cloud 独自の暗号化と HTTP-Live-Streaming(HLS)暗号化の 2 つの暗号化方式をサポートしています。Alibaba Cloud 独自の暗号化を使用することをお勧めします。このトピックでは、HLS 暗号化のしくみと使用方法について説明します。HLS 暗号化を使用して動画のセキュリティを確保し、動画をスムーズに再生するのに役立ちます。

しくみ

用語

MPS は、エンベロープ暗号化技術を使用して動画を暗号化します。Alibaba Cloud Key Management Service(KMS)を使用して、データキー(DK)とエンベロープデータキー(EDK)を生成できます。次に、DK を使用して動画を暗号化し、暗号化された動画を EDK とともに保存できます。動画を再生する場合、プレーヤーは復号サービスを使用して DK を取得し、動画を復号します。

説明

HLS 暗号化では、DK を保持する必要があります。

用語

説明

DK

DK はプレーンテキストキーとも呼ばれ、動画の暗号化に使用されます。

EDK

EDK は暗号文データキーとも呼ばれ、エンベロープ暗号化技術を使用して生成されます。DK の復号とプレーンテキストデータキーの取得に使用されます。

RAM

Resource Access Management(RAM)は、Alibaba Cloud が提供するサービスです。ユーザー ID とリソースアクセス権限を管理できます。詳細については、「RAM とは」をご参照ください。

KMS

KMS は、キー管理、データ暗号化、およびシークレット管理のためのエンドツーエンドの serviceplatform です。KMS は、データの暗号化と保護、およびシークレットの管理を行うためのシンプルで信頼性が高く、安全で標準に準拠した機能を提供します。詳細については、「KMS とは」をご参照ください。

Object Storage Service (OSS)

OSS は、Alibaba Cloud が提供するデータストレージサービスです。MPS ジョブのメディアファイルは、OSS バケットに保存されます。詳細については、「OSS とは」をご参照ください。

Alibaba Cloud CDN

HLS 暗号化の処理において、Alibaba Cloud CDN は M3U8 ファイル内の復号 Uniform Resource Identifier(URI)を動的に変更し、復号 URI をプレーヤーに返します。詳細については、「Alibaba Cloud CDN とは」をご参照ください。

暗号化プロセス

次の図は、MPS で動画を暗号化するプロセスを示しています。

mts_wf_hls_encrypt

  1. MPS、OSS、RAM、KMS、CDN の各サービスを有効にします。

  2. MPS に KMS へのアクセス権限を付与します。

    説明

    これにより、MPS は動画の暗号化中に KMS の GenerateDataKey 操作を呼び出して、DK と EDK を生成できます。

  3. MPS ジョブの出力ファイルを保存する OSS バケットに CDN 高速化ドメイン名を設定します。CNAME レコードを追加し、CDN 高速化ドメイン名の back-to-origin ホストを設定します。

  4. 動画暗号化のワークフローを作成し、出力ファイルを保存する OSS バケットやキー URI などの情報を指定します。

    キー URI は、サービスのエンドポイントを指定します。キー URI に関するデータは、動画の暗号化後に MPS によって生成された M3U8 ファイルに含まれています。

  5. 暗号化する動画をアップロードし、動画に作成したワークフローを指定します。

  6. 動画がアップロードされると、MPS は自動的にワークフローをトリガーします。

    次に、MPS は GenerateDataKey 操作を呼び出して DK と EDK を生成し、DK を使用して動画を暗号化します。動画が暗号化されると、MPS はキー URI と EDK に関するデータを M3U8 ファイルに書き込みます。

  7. MPS は、M3U8 ファイルと TS ファイルを出力ファイルを保存する OSS バケットに保存します。

復号プロセス

次の図は、HLS 暗号化された動画を復号するプロセスを示しています。

mts_hls_decrypt

  1. MtsHlsUriToken パラメーターを生成するトークン発行サービスを構築します。

    重要

    トークン発行サービスは、MtsHlsUriToken パラメーターを生成するために使用されます。

  2. KMS の Decrypt 操作を呼び出して復号サービスを構築し、DK をプレーヤーに返します。

    重要

    KMS の Decrypt 操作を呼び出して KMS から Base64 エンコードされた DK を取得した後、Base64 アルゴリズムを使用して DK をデコードし、デコードされた DK をプレーヤーに返します。

  3. MPS の QueryMediaList 操作を呼び出して M3U8 ファイルの OSS URL をクエリし、MtsHlsUriToken パラメーターを OSS URL に追加して、OSS URL をプレーヤーに返します。

  4. プレーヤーは MtsHlsUriToken パラメーターと DK を使用して、CDN から動画のストリーミング URL をリクエストします。CDN は M3U8 ファイルを変更し、キー URI と EDK をプレーヤーに返します。次に、プレーヤーは動画を復号して再生します。

コードロジック

HLS の暗号化と復号のプロセスでは、次のコードロジックを実装する必要があります。

  1. 動画暗号化のワークフローを作成します。

    説明

    MPS コンソールでワークフローを作成することもできますが、サーバー SDK を使用してワークフローを作成することをお勧めします。

  2. 復号トークンとして使用される MtsHlsUriToken パラメーターを生成するトークン発行サービスを構築します。復号トークンを確認します。各復号トークンは 1 回だけ使用することをお勧めします。

  3. KMS の Decrypt 操作を呼び出して復号サービスを構築します。Base64 アルゴリズムを使用して DK をデコードし、デコードされた DK をプレーヤーに返します。

前提条件

MPS で HLS 暗号化を使用する前に、次の準備を行ってください。

  1. MPS、OSS、KMS、RAM、CDN など、関連する Alibaba Cloud サービスを有効にします。

    これらのサービスを有効にしていない場合は、次の手順を実行します。

    1. MPS を有効にします。詳細については、「MPS の有効化」をご参照ください。

    2. OSS を有効にします。詳細については、「OSS の有効化」をご参照ください。

    3. KMS を有効にします。詳細については、「専用 KMS インスタンスの購入」をご参照ください。

    4. Alibaba Cloud CDN を有効にします。詳細については、「Alibaba Cloud CDN の有効化」をご参照ください。

  2. MPS に KMS へのアクセス権限を付与します。

    1. RAM コンソール にログインします。

    2. 左側のナビゲーションウィンドウで、承認する を選択します。[権限の付与] ページで、新規権限 をクリックします。[権限の付与] パネルが表示されます。

    3. [プリンシパル] 検索ボックスに AliyunMtsDefaultRole と入力し、システムによって作成され、MPS で使用できるロールを選択します。

    4. [ポリシー] セクションの検索ボックスに KMS と入力します。AliyunKMSFullAccess を選択し、[権限の付与] をクリックします。

    これにより、MPS に KMS へのアクセス権限が付与されます。MPS は動画の暗号化リクエストを受信すると、KMS の Decrypt 操作を呼び出して DK を取得できます。

  3. 出力ファイルを保存する OSS バケットに CDN 高速化ドメイン名を設定し、CDN 高速化ドメイン名の back-to-origin ホストを設定します。詳細については、「ドメイン名の追加」をご参照ください。CDN 高速化ドメイン名と back-to-origin ホストが設定されている場合は、この手順をスキップします。

    説明

    exampleBucket****.oss-cn-hangzhou.aliyuncs.com などの OSS バケットのパブリックドメイン名を入力できます。パブリックドメイン名は OSS コンソールで取得できます。または、同じ Alibaba Cloud アカウント内で、コンテンツ配信の高速化が必要な出力ファイルを保存する OSS バケットを選択することもできます。OSS バケットの内部ドメイン名はサポートされていません。

動画の暗号化

動画を暗号化するには、次の手順を実行します。

  1. 動画暗号化のワークフローを作成します。

    ワークフローを作成するには、Alibaba Cloud SDK を使用し、MPS の依存関係を追加する必要があります。使用するプログラミング言語に基づいて、ワークフロー作成のサンプルコードを表示できます。詳細については、次の表を参照してください。

    重要

    ワークフローを作成する際には、キー URI を指定する必要があります。動画の暗号化中に、MPS はキー URI を M3U8 ファイルに書き込み、出力ファイルを保存する OSS バケットにファイルを保存します。キー URI の例は example.aliyundoc.com です。

    プログラミング言語

    SDK

    サンプルコード

    Java

    Java 用 SDK

    HLS 暗号化のワークフローの作成

    Python

    Python 用 SDK

    HLS 暗号化のワークフローの作成

    PHP

    PHP 用 SDK

    HLS 暗号化のワークフローの作成

  2. 動画をアップロードしてワークフローをトリガーします。MPS コンソールまたは OSS コンソールで動画をアップロードできます。

    説明

    アップロード設定で動画に作成したワークフローを指定すると、動画のアップロード後に MPS が自動的にワークフローをトリガーします。

    動画が暗号化されたら、OSS コンソールにログインし、出力ファイルを保存する OSS バケットで M3U8 ファイルを表示します。次のサンプルコードは、M3U8 ファイルの例を示しています。

    #EXTM3U
         #EXT-X-VERSION:3
         #EXT-X-TARGETDURATION:5
         #EXT-X-MEDIA-SEQUENCE:0
         #EXT-X-KEY:METHOD=AES-128,URI="https://example.aliyundoc.com?Ciphertext=aabbccddeeff&MediaId=fbbf98691ea44b7c82dd75c5bc8b****"
         #EXTINF:4.127544,
         15029611683170-00001.ts
         #EXT-X-ENDLIST

    この例では、設定したキー URI と EDK が URI フィールドに含まれています。

HLS 暗号化された動画の再生

HLS 暗号化された動画を再生するには、次の手順を実行します。

  1. トークン発行サービスを構築します。

    説明

    高いセキュリティレベルを確保するには、暗号化方式に基づいてトークン発行サービスを構築する必要があります。

  2. 復号サービスを構築します。

    動画を復号し、復号キーを取得するためのローカル HTTP サービスを構築します。次のサンプルコードは、Java と Python で復号サービスを構築する方法の例を示しています。

    • Java のサンプルコード

      Java 用 SDK で必要な依存関係:

      Base64 アルゴリズムを使用した復号のサンプルコード:

      サンプルコード

      import com.sun.net.httpserver.*;
      import com.sun.net.httpserver.spi.HttpServerProvider;
      
      import java.io.IOException;
      import java.io.OutputStream;
      import java.net.HttpURLConnection;
      import java.net.InetSocketAddress;
      
      /**
       * *****   使用方法に関する注意事項     ******
       * このサンプルコードは、Base64 アルゴリズムを使用して DK をデコードします。
       * サンプルコードのポート番号は 8888 です。この番号がキー URI の番号と同じであることを確認してください。
        * 追加のトークン検証が必要な場合は、KMS を使用した復号の次のサンプルコードを参照してください。
       *
       * ***** コードロジック ******
       * 1. 復号リクエストを受信し、EDK を取得します。
       * 2. Base64 アルゴリズムを使用して DK をデコードし、デコードされた DK を返します。
       */
      public class Base64DecryptServer {
      
          public static void main(String[] args) throws IOException {
              Base64DecryptServer server = new Base64DecryptServer();
              server.startService();
          }
      
          public class Base64DecryptHandler implements HttpHandler {
              /**
               * 復号リクエストを処理します。
               * @param httpExchange
               * @throws IOException
               */
              public void handle(HttpExchange httpExchange) throws IOException {
                  String requestMethod = httpExchange.getRequestMethod();
                  if ("GET".equalsIgnoreCase(requestMethod)) {
                      // 復号キーは暗号キーと同じである必要があります。
                      byte[] key = "encryptionkey128".getBytes();
                      // ヘッダーを設定します。
                      setHeader(httpExchange, key);
                      // Base64 アルゴリズムでデコードされた DK を返します。
                      OutputStream responseBody = httpExchange.getResponseBody();
                      System.out.println(new String(key));
                      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);
              }
          }
          /**
           * サービスを開始します。
           * @throws IOException
           */
          private void startService() throws IOException {
              HttpServerProvider provider = HttpServerProvider.provider();
              // ポート 9999 でリスナーを設定し、一度に 30 件のリクエストを受け入れることができます。
              HttpServer httpserver = provider.createHttpServer(new InetSocketAddress(8888), 30);
              httpserver.createContext("/", new Base64DecryptHandler());
              httpserver.start();
              System.out.println("base64 hls decrypt server started");
          }
      
      }

      KMS を使用した復号のサンプルコード:

      サンプルコード

      import com.aliyun.mps.sdk.utils.InitClient;
      import com.aliyuncs.DefaultAcsClient;
      import com.aliyuncs.exceptions.ClientException;
      import com.aliyuncs.http.ProtocolType;
      import com.aliyuncs.kms.model.v2016010.DecryptRequest;
      import com.aliyuncs.kms.model.v20160120.DecryptResponse;
      import com.sun.net.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;
      
      /**
       * *****   使用方法に関する注意事項     ******
       * このサンプルコードは、M3U8 暗号化と書き換え機能が無効になっている KMS を使用して復号サービスを構築します。MtsHlsUriToken パラメーターは検証されません。
       * サンプルコードのポート番号は 8888 です。この番号がキー URI の番号と同じであることを確認してください。
       *
       * ***** コードロジック ******
       * 1. 復号リクエストを受信し、EDK を取得します。
       * 2. KMS の Decrypt 操作を呼び出して DK を取得します。
       * 3. Base64 アルゴリズムを使用して DK をデコードし、デコードされた DK を返します。
       */
      public class HlsDecryptServerNoToken {
      
          private static DefaultAcsClient client;
          static {
              try{
                  client = InitClient.initMpsClient();
              }catch (Exception e){
                  e.printStackTrace();
              }
          }
      
          public static void main(String[] args) throws IOException {
              HlsDecryptServerNoToken server = new HlsDecryptServerNoToken();
              server.startService();
          }
      
          public class HlsDecryptHandler implements HttpHandler {
              public void handle(HttpExchange httpExchange) throws IOException {
                  String requestMethod = httpExchange.getRequestMethod();
                  if(requestMethod.equalsIgnoreCase("GET")){
                      // 動画 URL から EDK を取得します。
                      String ciphertext = getCiphertext(httpExchange);
                      System.out.println(ciphertext);
                      if (null == ciphertext)
                          return;
                      // KMS から取得した DK を復号し、Base64 アルゴリズムを使用して DK をデコードします。
                      byte[] key = decrypt(ciphertext);
                      // ヘッダーを設定します。
                      setHeader(httpExchange, key);
                      // デコードされた DK を返します。
                      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);
              }
      
              private byte[] decrypt(String ciphertext) {
                  DecryptRequest request = new DecryptRequest();
                  request.setCiphertextBlob(ciphertext);
                  request.setProtocol(ProtocolType.HTTPS);
                  try {
                      DecryptResponse response = client.getAcsResponse(request);
                      String plaintext = response.getPlaintext();
                      // 注:Base64 アルゴリズムを使用して DK をデコードする必要があります。
                      return Base64.decodeBase64(plaintext);
                  } catch (ClientException e) {
                      e.printStackTrace();
                      return null;
                  }
              }
              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("Ciphertext が見つかりません");
                      return null;
                  }
              }
          }
      
          /**
           * サービスを開始します。
           *
           * @throws IOException
           */
          private void startService() throws IOException {
              HttpServerProvider provider = HttpServerProvider.provider();
              // ポート 8888 でリスナーを設定し、一度に 30 件のリクエストを受け入れることができます。ビジネス要件に基づいてポートを変更できます。
              HttpServer httpserver = provider.createHttpServer(new InetSocketAddress(8888), 30);
              httpserver.createContext("/", new HlsDecryptHandler());
              httpserver.start();
              System.out.println("no token hls decrypt server started");
          }
      
      }
    • Python のサンプルコード

      Python 用 SDK で必要な依存関係:

      • pip install aliyun-python-sdk-core

      • pip install aliyun-python-sdk-kms

      • pip install aliyun-python-sdk-mts

      Python のサンプルコード:

      サンプルコード

      # -*- coding: UTF-8 -*-
      from http.server import BaseHTTPRequestHandler, HTTPServer
      from urllib.parse import urlparse, parse_qs
      from aliyunsdkcore.client import AcsClient
      from aliyunsdkcore.request import CommonRequest
      import cgi
      import json
      import base64
      import logging
      from urllib.parse import urlparse
      
      logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
      # access_key_id、access_secret、region_id を置き換えてください
      client = AcsClient("","")
      
      class AuthorizationHandler(BaseHTTPRequestHandler):
        def do_GET(self):
          #self.check()
          self.set_header()
          cipertext = self.get_cihpertext()
          #print(cipertext)
          plaintext = self.decrypt_cihpertext(cipertext)
          #print(plaintext)
          key = base64.b64decode(plaintext)
          #print(key)
          self.wfile.write(key)
      
        def do_POST(self):
          pass
        
        def check(self):
      # MtsHlsUriToken などを確認します。
          pass
        
        def set_header(self):
          self.send_response(200)
      # cors
          self.send_header('Access-Control-Allow-Origin', '*')
          self.end_headers()
      
        def get_cihpertext(self):
          path = urlparse(self.path)
          query = parse_qs(path.query) 
          return query.get('Ciphertext')[0]
          
        def decrypt_cihpertext(self, cipertext):
          request = CommonRequest()
          request.set_domain('')
          request.set_version('2014-06-18')
          request.set_action_name('DecryptKMSDataKey')
          request.add_query_param('CipherText', cipertext)
      
          response = client.do_action_with_exception(request)
          # print("####################################")
          # print(response)
          jsonResp = json.loads(response)
          return jsonResp["PlainText"]
        
      if __name__ == '__main__':
      # シンプルなサーバーを起動し、永久にループします
        print("サーバーを起動しています。停止するには   を使用します")
        server = HTTPServer(('127.0.0.1', 8099), AuthorizationHandler)
        server.serve_forever()
  3. MPS の QueryMediaList 操作を呼び出して、動画のストリーミング URL をクエリします。

    OpenAPI Explorer で操作を呼び出すか、SDK を統合することで呼び出すことができます。

  4. 暗号化された動画を再生します。

    ApsaraVideo Player またはサードパーティのプレーヤーを使用して、暗号化された動画を再生できます。

    • サードパーティのプレーヤーを使用する場合は、再生ロジックを指定します。

    • ApsaraVideo Player を使用する場合は、動画が再生される前に、必要に応じてセキュリティトークンと認証情報を取得します。詳細については、「動画の再生」をご参照ください。

    また、オンラインプレーヤーを使用して、HLS 暗号化によって暗号化された動画の再生をテストすることもできます。

    たとえば、ApsaraVideo Player 診断ツール を使用できます。このツールを使用する場合は、[ソース] フィールドに動画のストリーミング URL を入力し、[再生] をクリックします。

    説明

    ブラウザのデバッグページで、プレーヤーが認証サーバーにリクエストを送信し、復号キーを取得してから、動画を復号して再生することがわかります。

    次の手順では、ApsaraVideo Player が再生をテストする方法について説明します。

    • ApsaraVideo Player はストリーミング URL を受信すると、OSS バケットのドメイン名を CDN 高速化ドメイン名に置き換えます。次に、ApsaraVideo Player は、復号トークンとして使用される MtsHlsUriToken パラメーターを CDN 高速化ドメイン名に追加し、変更されたストリーミング URL のリクエストを CDN に送信します。リクエストの例:https://example.aliyundoc.com/test_01.m3u8?MediaId=fbbf98691ea44b7c82dd75c5bc8b****&MtsHlsUriToken=<Token>

      重要

      ApsaraVideo Player を使用すると、MtsHlsUriToken パラメーターが自動的に追加されます。他のプレーヤーを使用する場合は、MtsHlsUriToken パラメーターを手動で追加する必要があります。

    • CDN はリクエストを受信すると、M3U8 ファイル内のキー URI を動的に変更し、変更されたストリーミング URL をプレーヤーに返します。たとえば、元のストリーミング URL が https://example.aliyundoc.com?Ciphertext=aabbccddeeff&MediaId=fbbf98691ea44b7c82dd75c5bc8b**** の場合、返されるストリーミング URL は https://example.aliyundoc.com?Ciphertext=aabbccddeeff&MediaId=fbbf98691ea44b7c82dd75c5bc8b****&MtsHlsUriToken=<Token> です。

    • プレーヤーは M3U8 ファイルの EXT-X-KEY タグにある URI を解析してアクセスし、復号キーを取得します。KMS の Decrypt 操作を呼び出し、取得した DK を Base64 アルゴリズムを使用してデコードし、デコードされた DK をプレーヤーに返します。プレーヤーは DK を使用して TS ファイルを復号し、動画を再生します。

参照

Alibaba Cloud 独自の暗号化