- 本文仅用于技术原理分析和个人学习研究,不构成任何违法行为。
- 本文不提供任何破解工具、脚本或可执行代码
- 本文不鼓励、不支持任何侵犯知识产权的行为
- 本人为该平台付费用户,分析内容基于个人学习目的
请遵守《中华人民共和国著作权法》及相关法律法规
0x00 引言
在线教育平台普遍采用视频加密技术来保护付费内容。以小某通为例,其点播视频使用了基于HLS的AES-128加密方案。作为付费用户,我遇到了以下问题:
- 视频有有效期限制(购买后仅能观看至特定日期)
- 不提供离线下载功能
- 电脑端播放受限
出于对技术好奇心,我对小某通的视频加密方案进行了分析。本文将从HLS协议基础出发,解读其加密实现原理。
0x01 HLS基础
什么是HLS?
HLS(HTTP Live Streaming)是Apple提出的基于HTTP的流媒体传输协议。其核心思想是将视频切分成小片段(通常 2-10 秒),通过HTTP逐段传输。
HLS 的优势在于:
- 基于标准HTTP,不需要特殊端口
- 支持CDN,分发效率高
- 自适应码率
m3u8播放列表
HLS使用m3u8格式的播放列表来描述视频内容。一个典型的m3u8文件内容如下:
#m3u8 file example
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:2
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:2,
main_0.ts?sign=xxx&t=xxx&us=xxx
#EXTINF:2,
main_1.ts?sign=xxx&t=xxx&us=xxx
#EXTINF:2,
main_2.ts?sign=xxx&t=xxx&us=xxx
标签说明:
| 标签 | 含义 |
| EXT-X-TARGETDURATION | 每个分片的最大时长(秒) |
| EXT-X-MEDIA-SEQUENCE | 第一个分片的序列号 |
| EXTINF | 每个分片的实际时长 |
多级m3u8
HLS支持多级播放列表(Master Playlist),用于提供多种画质选择
#m3u8 master playlist file example
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=640x360
360p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2000000,RESOLUTION=1280x720
720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080
1080p.m3u8
播放器会根据带宽自动选择合适的画质,也可以手动指定最高画质(选择BANDWIDTH最大的流)
0x02 AES-128加密流程
HLS协议原生支持AES-128加密,这正是是小某通采用的DRM方案。当然,HLS协议的DRM有很多种,在此只以AES-128加密的HLS为主。
加密原理
加密过程
明文视频
↓ H.264/AAC 编码
↓ 切分为TS分片(每个2秒)
↓ AES-128-CBC加密
↓ 存储到CDN
加密后的TS分片
解密过程(播放器端)
播放器请求m3u8
↓ 解析#EXT-X-KEY标签
↓ 获取密钥URI
↓ 请求密钥(HTTP GET)
↓ 拿到16字节AES密钥
↓ 逐个下载TS分片
↓ AES-128-CBC解密
↓ 去除PKCS7填充
播放明文视频
m3u8中的加密信息
加密的m3u8会在每个分片之前标注密钥信息:
# m3u8 encryption file example
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:2
#EXT-X-KEY:METHOD=AES-128,URI="https://key-server.com/api/keys?ak=xxx",IV=0x00000000000000000000000000000000
#EXTINF:2,
main_0.ts?sign=xxx
#EXTINF:2,
main_1.ts?sign=xxx
参数说明:
| 参数 | 含义 |
| METHOD=AES-128 | 加密算法为 AES-128 |
| URI | 密钥获取地址 |
| IV | 初始化向量(16 字节) |
AES-128-CBC模式
AES(Advanced Encryption Standard)是一种对称加密算法,128 位密钥长度。CBC(Cipher Block Chaining)模式的工作方式:
明文分片 P1 P2 P3 ...
↓ ↓ ↓
XOR IV XOR C1 XOR C2
↓ ↓ ↓
AES AES AES
↓ ↓ ↓
密文分片 C1 C2 C3 ...
每个明文块先与前一个密文块异或,再进行 AES 加密。第一个块使用 IV(初始化向量)。
IV的来源
IV在这其实有两种常见取值方式:
- m3u8 中显式指定:IV=0x00000000000000000000000000000001
- 使用媒体序列号:当平台未在
EXT-X-KEY中显式提供IV时,才会使用媒体序列号作为IV
一般来说,以上取值方式只能是二选一的。在该平台的实现当中未在EXT-X-KEY里面提供IV值,故平台实际使用上述的第二种取值方式作为IV:
# 此处的IV计算方式
iv = media_sequence_number.to_bytes(16, byteorder='big')
PKCS7 填充
AES加密要求明文长度是16字节的倍数。当最后一块不足16字节时,使用PKCS7填充:
原始数据: [AB] (1 字节)
填充后: [AB 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E] (16 字节)
↑填充字节 ↑填充数量=14=0x0E
解密后需要去掉填充:检查最后一个字节的值,去掉对应数量的字节。
0x03 小某通的实现
资源类型
根据目前我探测到的小某通的课程资源分为两大类(其实是我的课程只有这两类):
| 类型 | 加密方式 |
| 直播回放 | 通常未加密 |
| 点播视频 | AES-128 DRM或未加密 |
综上所述,可以得出该平台直播回放通常使用普通的明文HLS流,而点播视频使用加密的HLS流。在此我们就不说未加密的点播视频流了,此处我们就说加密的视频流。
点播视频的加密流程
1. 获取视频信息
POST相关视频信息接口
→ 返回加密的m3u8地址(含play_sign、material_id等签名)
2. 下载m3u8
GET相关m3u8接口
→ 返回加密的播放列表
3. 解析密钥地址
从m3u8中提取#EXT-X-KEY的URI
4. 获取解密密钥
GET密钥结构
→返回16字节的AES密钥
5. 解密分片
下载每个.ts分片后,播放器会在已授权会话当中处理加密媒体分片并完成播放
密钥分发机制
该平台的密钥通过 KDS(Key Distribution Service)接口分发,密钥获取的认证链路:
浏览器登录→Cookie中包含登录态
→ 请求视频详情API→获取加密m3u8
→ 从m3u8中解析密钥URL
→ 请求密钥接口(需要有效的Cookie)
→ 返回AES密钥
play_sign与material_id
视频详情接口返回的play_sign和material_id是平台的签名机制:
- play_sign:播放签名,用于验证播放权限
- material_id:素材标识,关联 CDN 上的视频资源
这些参数确保只有授权用户才能获取到有效的播放地址和密钥。
0x04 安全性分析
该平台采用的AES-128 HLS加密属于传输层加密,而非端到端的DRM:
视频 → AES加密 → CDN存储 → 播放器解密播放
↑
密钥在客户端获取
(Cookie 鉴权即可)
密钥最终还是会在客户端的请求中出现,因此这种方案的本质是防"君子"不防"小人"。
0x05 结语
HLS AES-128加密是一种简单有效且暴力的传输加密方案,适合防止普通人随意下载,但无法抵御有相关技术人员的逆向分析。加密密钥在客户端获取是该方案其根本弱点。
加密技术没有绝对的壁垒,任何在客户端运行的解密逻辑,本质上用透明纸糊的门然后还把钥匙放在地垫下面。AES-128如此,Widevine L3另一种DRM方式如此,未来大多数基于软件的DRM亦如此。真正的安全边界不在于算法,而在于密钥的存储与分发方式——只要密钥需要到达客户端,就一定存在被提取的可能。
以上就是纯技术分析。本文不提供任何完整代码或破解工具,仅供学习交流。
本文基于公开的HLS标准文档和逆向分析编写,所有技术细节均可在Apple 的 HLS 文档中找到。