亚马逊AWS官方博客

使用亚马逊云科技 Elemental MediaConvert 实现 HLS 标准加密

背景

HTTP Live Streaming(HLS) 作为流行的流媒体协议,已经广泛应用在娱乐、教育等行业的直播、点播场景。通过将整个媒体文件切分为多个小的可以通过 HTTP 下载的媒体切片文件,然后提供一个配套的媒体切片索引文件(m3u8),提供给客户端,让客户端顺序地拉取这些媒体文件实现播放。

Elemental MediaConvert 是亚马逊云科技的一款基于文件的视频处理服务,允许具有任意规模内容库的视频提供商轻松可靠地对用于广播和多屏交付的内容进行转码,例如将 MP4 文件转码为适合点播的 HLS 文件。

随着版权保护需求的增长,如何防止媒体资源的非授权访问显得十分重要。HLS 标准加密就是一种防护手段,它通过 AES 算法对 HLS 切片文件进行加密。播放时需要先获取到密钥才能正常播放媒体文件,通过限制密钥文件的访问就可以实现媒体资产的保护。

HLS m3u8 索引文件样例对比

## 未使用加密的 m3u8 文件
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:3
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:3,
i9243290432_Ott_Hls_Ts_Avc_Aac_16x9_960x540p_3.5Mbps_qvbr_00001.ts
#EXTINF:3,
i9243290432_Ott_Hls_Ts_Avc_Aac_16x9_960x540p_3.5Mbps_qvbr_00002.ts


## 使用标准加密的 m3u8 文件
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:3
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-KEY:METHOD=AES-128,URI="https://d1nhxos9limlh4.cloudfront.net/keys/enc.key",IV=0x00000000000000000000000000000001
#EXTINF:3,
i9243290432_Ott_Hls_Ts_Avc_Aac_16x9_960x540p_3.5Mbps_qvbr_00001.ts
#EXT-X-KEY:METHOD=AES-128,URI="https://d1nhxos9limlh4.cloudfront.net/keys/enc.key",IV=0x00000000000000000000000000000002
#EXTINF:3,
i9243290432_Ott_Hls_Ts_Avc_Aac_16x9_960x540p_3.5Mbps_qvbr_00002.ts

HLS 标准(AES-128) 加密实现媒体内容保护的工作流程

  1. 服务器端:将每个视频片段用 AES-128 算法加密
  2. 密钥分发:通过单独的安全通道提供解密密钥
  3. 客户端:播放器获取加密的视频片段和密钥
  4. 实时解密:播放器用密钥解密片段并播放

目前 HLS 标准加密在播放器端已有广泛的支持,比如 Safari 浏览器、video.js、HLS.js 等组件,因此可以作为一种通用的媒体保护手段应到到点播业务系统中。本文将演示如何通过 Elemental MediaConvert 转码实现 HLS 加密并通过 Lambda@Edge 实现动态密钥访问权限校验。

方案介绍

HLS 切片加密后,在没有密钥的情况下将无法正常播放视频文件,因此密钥的访问保护尤为重要。由于在 MediaConvert 转码后,一个 m3u8 索引文件中视频切片的密钥是固定的。校验不同用户权限常见的方式是将密钥文件单独存储,在用户通过后端应用校验之后保留一个凭证在播放器端,在请求密钥时作为 header/query string传递给密钥服务器进行校验。本文假定密钥校验凭证已由后端生成,演示如何使用 Lambda@Edge 将凭证附加到 m3u8 文件中的密钥 URL 以实现动态权限校验。

本文演示的方案示意图如下,每步骤功能说明如下:

    1. 用户登录后通过后端接口校验权限
    2. 根据用户权限,生成 token,附加为 m3u8 URL 的 query string
    3. 播放器根据步骤 2 中后端提供的 URL 从 CloudFront 请求 m3u8 文件。Lambda@Edge 更新 m3u8 文件内容,将 token 作为 query string 添加至 m3u8 文件中的密钥 URL
    4. 播放器通过带 token 的 URL 请求密钥,CloudFront 可通过 CloudFront Function + KV Store 或者 Lambda@Edge 校验请求权限
    5. 播放器根据步骤 3 获取的 m3u8 文件获取 ts 切片,使用步骤 4 获取的密钥解密并完成播放

配置步骤

HLS 加密密钥准备

  1. 创建 AES 密钥,上传至密钥分发服务器(本文中选择为 CloudFront + S3),并记录其访问地址如https://d1234546.cloudfront.net/enc.key
openssl rand 16 > enc.key
  1. 将二进制密钥文件转为 16 进制字符串,保存备用。MediaConvert 转码任务加密 HLS 切片文件时依赖此字符串
xxd -p enc.key

Elemental MediaConvert 转码任务加密相关配置

本截图展示转码任务加密相关配置,其余配置请参考文末相关链接。

Lambda@Edge 配置(绑定媒体资源 CloudFront 分发)

示例 Lambda@Edge 代码如下,其绑定事件为 origin response。其主要目的是将权限校验query string 添加至m3u8 中密钥文件地址供密钥分发服务器校验,确保授权用户能够正常获取到密钥。

import urllib3
import re

def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']
    response = event['Records'][0]['cf']['response']
    
    # Extract token from query string
    token = None
    for param in request['querystring'].split('&'):
        if param.startswith('token='):
            token = param.split('=')[1]
            break
    
    if not token or response['headers'].get('content-type', [{}])[0].get('value') != 'application/vnd.apple.mpegurl':
        return response
    
    try:
        # Fetch original content
        http = urllib3.PoolManager()
        origin_host = event['Records'][0]['cf']['config']['distributionDomainName']
        url = f"https://{origin_host}{request['uri']}"

        
        resp = http.request('GET', url)
        original_content = resp.data.decode('utf-8')

        
        # Modify M3U8 content - only add token to EXT-X-KEY URIs
        def add_token_to_key(match):
            uri_part = match.group(1)
            separator = '&' if '?' in uri_part else '?'
            return f'URI="{uri_part}{separator}token={token}"'
        
        modified_content = re.sub(r'URI="([^"]+)"', add_token_to_key, original_content)
    

        response['body'] = modified_content
        return response
    except Exception as e:

        return response

播放验证

使用 Safari 或者播放器组件打开转码后的 m3u8 文件,可以留意到 token query string 被成功添加到加密密钥 URL。密钥服务通过 token 即可确认当前用户是否有权限访问文件。

总结

本文首先介绍了使用 Elemental MediaConvert 实现 HLS 标准加密,并使用 Lambda@Edge 更新 m3u8 文件实现密钥权限动态验证的方案,以实现媒体资产的保护。如果需要级别更高的保护,还可以参考第三方服务商提供的 DRM 方案。

参考资料

  1. Elemental MediaConvert 介绍 http://amazonaws.cn/mediaconvert/features/
  2. Elemental MediaConvert 创建转码作业 https://docs.aws.amazon.com/mediaconvert/latest/ug/creating-a-job.html
  3. 使用CloudFront signed URL 保护 HLS 资源 https://github.com/aws-samples/amazon-cloudfront-protecting-hls-manifest-with-signed-url/
  4. 通过加密和 DRM 保护您的媒体资产 https://docs.aws.amazon.com/zh_cn/mediaconvert/latest/ug/using-encryption.html

*前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。

本篇作者

李寅祥

AWS 解决方案架构师,负责基于AWS云计算方案架构的咨询和设计,在国内推广AWS云平台技术和各种解决方案。曾就职于IBM,负责企业私有云方案咨询和架构设计,在基础架构方面有丰富经验。