视频 App 与 DRM 案例
视频 App 与 DRM 案例
📚 前置知识
本案例涉及以下核心技术,建议先阅读相关章节:
视频类 App 的逆向分析是移动端安全领域最具挑战性的方向之一,其核心难点在于数字版权管理(DRM)技术的对抗。本案例将深入探讨视频 App,特别是涉及 DRM 的分析思路。
核心分析目标
- 视频流分析: 解析视频播放的网络协议,如
HLS(.m3u8) 和DASH(.mpd),并提取视频分片。 - 解锁 VIP 功能: 绕过付费墙,观看 VIP 专属影片或解锁更高清晰度(如 1080p, 4K)。
- DRM 对抗: 理解 DRM 的工作原理,并尝试获取解密视频所需的密钥。(注意:这通常是极其困难的,且可能涉及法律风险。)
案例:分析一个使用 Widevine DRM 的视频播放流程
💡 思路一句话: 拦截视频播放请求 → 分析 DRM license 获取流程 → hook MediaDrm API 提取会话密钥 → 理解内容解密链路。本案例以 Widevine L3 为例,不涉及 L1 硬件安全。
第 1 步:视频流协议分析
目标: 找到描述视频信息的清单文件 (.m3u8 或 .mpd)。
- 网络抓包: 打开 Charles 或 Mitmproxy,启动目标视频 App 并播放一个影片。
- 过滤请求: 在抓包结果中,使用关键词
m3u8或mpd进行过滤。你很快就能定位到一个请求,其 URL 类似于https://.../video.mpd。 - 分析清单文件:
DASH (
.mpd): 这是一个 XML 文件,描述了视频的各种信息,包括不同的分辨率、音轨、字幕轨道以及加密信息。HLS (
.m3u8): 这是一个文本文件。主m3u8文件可能指向多个子m3u8文件,每个子文件代表一种特定的码率(清晰度),并包含了该码率下所有视频分片(.ts文件)的 URL。
在清单文件中,你会找到一个关键的标签,表明内容是受保护的,例如:
| |
第 2 步:理解 DRM 工作流程 (Widevine)
Google 的 Widevine 是 Android 平台上最主流的 DRM 方案。它分为三个安全级别 (L1, L2, L3),其中 L1 安全性最高。
- App 请求播放: App 从视频清单中解析出
pssh数据。 - 获取许可证 (License): App 将
pssh数据发送给系统的MediaDrmAPI,生成一个许可证请求(License Request)。然后,App 将这个请求发送到视频服务提供商的许可证服务器。 - 服务器验证: 许可证服务器验证请求的合法性(例如,验证用户的 VIP 身份),然后返回一个加密的许可证(Encrypted License)。
- 解密密钥: App 将加密的许可证提供给
MediaDrmAPI。这一步是关键:
L1 安全级别: 许可证的处理和内容密钥的解密完全在处理器的可信执行环境(TEE)中进行。Android 操作系统和 App 本身都无法访问到解密后的密钥。视频帧的解密也在 TEE 中完成,然后直接输出到屏幕,不会在 App 的内存中暴露。
L3 安全级别: 在没有 TEE 支持的设备上,这些操作都在软件层面完成。因此,L3 是理论上最容易被攻击的。
第 3 步:逆向分析与信息获取
由于 L1 的硬件级保护,直接获取内容密钥(Content Key)几乎是不可能的,但在一些 arxiv 论文中,笔者确实找到了在一些特定设备中可以利用的漏洞。因此,分析的重点转向了许可证的获取过程。
目标: 拦截 App 与许可证服务器之间的通信,获取许可证请求和响应。
- 定位许可证请求代码:
搜索
MediaDrm,getKeyRequest,provideKeyResponse等android.media包中的 DRM 相关 API。使用 Frida Hook 这些方法,可以打印出
pssh、许可证请求和加密的许可证响应。
| |
- CDM (内容解密模块) 分析: Widevine 的 L3 级 CDM 是一个原生库(
.so文件),负责处理白盒加密的逻辑。对这个.so文件进行深入的静态和动态分析,是理论上还原出设备密钥(Device Key)的唯一途径,这也是 CDM Challenge 等比赛的核心。这是一个极其复杂和耗时的过程。
主流平台 DRM 与加密方案实例
国内平台 (某酷、某奇艺、某讯视频、某果 TV)
国内主流视频平台在加密策略上通常采用**“自研加密方案 + 标准 DRM”**的混合模式。
对于拥有全球版权的影视剧(如好莱坞大片),它们会使用行业标准的 Widevine DRM。
对于大量的自制剧、综艺等内容,它们更倾向于使用自研的加密方案,其核心是对 HLS 协议进行改造。
通用模式:保护 HLS 密钥的获取过程
- 视频流: 普遍使用 HLS (
.m3u8) 协议。 - 加密算法:
.m3u8文件中会声明视频分片(.ts文件)使用AES-128-CBC加密。 - 核心保护: 视频数据本身的加密算法是标准的,但获取解密密钥(Key)的过程是高度定制和保护的。
.m3u8文件本身不是静态的,而是通过一个需要复杂签名的 API 动态生成的。#EXT-X-KEY标签中指向的密钥 URL (key.key) 也不是一个能直接访问的地址,访问它同样需要正确的 Cookie、Referer 和加密参数。
- 逆向关键:
定位播放 API: 逆向的重点是找到 App 中负责请求视频播放信息的 API。这个 API 的请求参数通常包含视频 ID、清晰度、以及一个类似我们在上一章分析过的、包含设备指纹和时间戳的
sign或token。模拟合法请求: 只要能够成功模拟这个 API 的调用,就能获取到一个包含了有效密钥 URL 的
.m3u8文件。拿到密钥后,就可以使用标准的AES-128算法解密.ts文件并合并成一个完整的视频。某讯视频的
vkey: 一个典型的例子是某讯视频,其播放 API 中需要一个至关重要的vkey参数,这个参数的生成算法就封装在客户端的 SO 库中。
国外平台 (Netflix, 某管, Hulu, HBO Max)
国外主流视频平台,特别是内容提供商,严格且深度地依赖标准化的 DRM 体系。逆向的焦点完全不在于分析视频文件格式或算法,而在于 DRM 许可证的获取流程。
Netflix / Hulu / HBO Max
DRM 方案: 在 Android 上无一例外地使用 Google Widevine,在苹果设备上使用 FairPlay。
安全级别: 对于高清内容(HD, 4K),强制要求设备的 Widevine 安全级别为 L1。这意味着密钥交换和内容解密全程在硬件 TEE 中完成,App 和操作系统均无法触及明文密钥。
许可证请求保护: 逆向的唯一着眼点是 App 发起许可证请求的过程。
这个请求被多种方式保护,例如 Netflix 使用自研的 MSL (Message Security Layer) 协议对许可证请求本身进行二次封装和加密。
App 会采集大量设备指纹信息,连同用户的身份凭证一起,用于生成许可证请求。服务端的风控系统会严格校验这些信息,以确保请求来自于一个合法的、未被篡改的官方 App 客户端。
逆向结论: 在 L1 保护下,通过逆向 App 来获取视频解密密钥以进行离线下载是几乎不可能的。分析的主要意义在于理解其架构和安全强度。
某管
某管的情况比较特殊,它需要区分对待:
付费内容 (某管 Premium / 电影): 与 Netflix 类似,使用标准的 Widevine DRM 进行保护。
普通 UGC 内容: 大部分视频没有使用 DRM 加密,但使用了另一种巧妙的保护方式——动态 URL 签名。
现象: 使用
yt-dlp等工具下载视频时,会看到它有一个"deciphering signature"的过程。原理: 视频流的 URL 中包含一个
s或sig参数,这个签名是由一段混淆过的 JavaScript 代码(在 Web 端)或 Native 代码(在 App 端)动态生成的。该算法将视频的cipher(一段加密字符串) 和其他参数作为输入,输出一个解密的签名。逆向关键: 逆向的重点不再是 DRM,而是找到并还原那段负责计算签名的 JavaScript/Native 函数。由于代码经过了高度混淆,这依然是一项具有挑战性的工作。
音乐流媒体平台 (某果音乐, 某破天)
音乐流媒体平台同样采用 DRM 保护其内容,但由于音频文件体积较小、交互模式不同,其加密方案与视频平台有所差异。
某果音乐
某果音乐采用 Widevine DRM + HLS 的组合方案保护其音频内容。
认证体系:
- accessToken: 从 Web 端 JavaScript 中提取的 JWT Token,用于 API 认证
- mediaUserToken: 用户身份令牌,存储在 Cookie 中,用于访问个人化内容和高品质音源
API 架构:
| |
DRM 解密流程:
- 从 webPlayback 接口获取 HLS 播放列表 URL
- 解析
.m3u8文件,提取#EXT-X-KEY中的 PSSH 数据 - 使用 Widevine CDM 构造 License Challenge
- 向
hls-key-server-url发送许可证请求 - 解析 License 响应,提取 AES 解密密钥
- 使用密钥解密音频分片
| |
音频格式: 主要使用 28:ctrp256 格式 (256kbps AAC),通过 HLS 协议分发。
某破天
某破天 采用双轨加密方案,根据音频格式使用不同的加密机制。
认证体系:
- sp_dc Cookie: 用户会话凭证,从浏览器 Cookie 中提取
- TOTP 令牌: 时间动态令牌,用于生成 accessToken (详见 TOTP 技术原理)
- Client Token: 设备认证令牌,包含设备指纹信息
TOTP 认证机制 (关键反爬措施):
| |
API 架构:
| |
双轨加密方案:
| 格式 | 加密方式 | 品质 | 密钥获取 |
|---|---|---|---|
| OGG Vorbis | PlayPlay (AES-CTR) | 96/160/320 kbps | PlayPlay API |
| AAC (M4A) | Widevine DRM | 128/256 kbps | Widevine License API |
PlayPlay 解密 (Vorbis 格式):
| |
JA3 指纹检测绕过:
某破天 使用 JA3 指纹检测来识别非官方客户端。绕过方案:
| |
无头浏览器保活 (Token 自动刷新):
某破天 的 accessToken 有效期较短,且 TOTP 认证可能被风控拦截。使用无头浏览器可以模拟真实用户行为,自动获取新的 Token:
| |
保活策略:
- 定时任务每 30-50 分钟刷新 Token (有效期约 1 小时)
- 在 License 请求失败 (403) 时自动触发刷新
- 使用 Cookies 而非账号密码,避免登录风控
- 模拟真实浏览器指纹,绕过自动化检测
逆向要点:
- TOTP 参数需要动态获取,某破天 会定期更新
- 高品质音源 (320kbps Vorbis, 256kbps AAC) 需要 Premium 账户
- PlayPlay 的 Nonce 和 IV 是固定的,但密钥是动态获取的
- Client Token 包含设备指纹,用于风控检测
- 建议使用无头浏览器保活方案,比纯 API 方式更稳定
视频平台 API 签名实战
💡 思路一句话: 抓包定位签名参数(通常在 URL query 或请求头中)→ jadx 搜索参数名追溯签名生成逻辑 → Frida hook 签名函数验证 → 还原签名算法。
以下是基于 yt-dlp 项目的真实实现分析,展示了如何逆向还原各平台的视频获取逻辑。
B 某站 WBI 签名机制
B 某站使用 WBI (Web 接口签名) 机制保护其 API 接口。
WBI 密钥获取与签名
| |
视频格式提取
| |
某奇艺 SDK 签名算法
某奇艺使用复杂的 SDK 进行请求签名,其核心是多轮 MD5 变换。
SDK 解释器实现
| |
登录与密钥获取
| |
某讯视频 cKey 加密
某讯视频使用 AES-CBC 加密生成 cKey 参数。
cKey 生成算法
| |
某酷 CNA 设备标识
某酷使用 CNA (Client Network Address) 作为设备标识。
| |
某果 TV tk2 令牌
某果 TV 使用 Base64 编码的设备信息 作为令牌。
| |
某管 Innertube 客户端体系
某管使用 Innertube API 与多种客户端类型进行通信。
客户端配置
| |
签名解密机制
某管对视频 URL 使用 动态 JavaScript 签名 保护:
| |
视频平台逆向要点对比
| 平台 | 签名机制 | 加密方式 | 设备标识 | 难度 |
|---|---|---|---|---|
| B 某站 | WBI (md5 + 置换表) | 无 | SESSDATA Cookie | 中 |
| 某奇艺 | SDK (多轮 md5) | RSA 登录 | IP + 时间戳 | 高 |
| 某讯视频 | cKey (AES-CBC) | DRM 可选 | GUID | 高 |
| 某酷 | CNA (ETag) | 无 | utid/ysuid | 低 |
| 某果 TV | tk2 (Base64) | 无 | UUID | 低 |
| 某管 | Innertube + JS 签名 | DRM 可选 | PoToken | 高 |
| 某果音乐 | JWT + mediaUserToken | Widevine (HLS) | 设备证书 | 高 |
| 某破天 | TOTP + ClientToken | Widevine/PlayPlay | sp_dc + JA3 | 高 |
通用逆向策略
1. 网络层分析
| |
2. 前端 JS 逆向
| |
3. 设备模拟
| |
总结
视频 App 的 DRM 逆向是一场与硬件和复杂密码学协议的艰苦斗争。与音乐 App 不同,其核心目标通常不是开发一个"下载器",而是理解其安全体系的强度和弱点。
对于普通分析,重点是拦截和理解信令(清单文件、许可证请求/响应)。
对于高级研究,核心是攻击 L3 的 CDM 实现,但这需要极高的逆向工程和密码学知识。
这个领域的攻防水平代表了整个行业安全对抗的顶峰。
通过分析 yt-dlp 项目的实现,我们可以看到:
- 签名算法多样性: 从简单的 MD5 到复杂的多轮变换,各平台都有独特的保护机制
- 客户端模拟的重要性: 正确的 User-Agent 和设备标识是成功请求的关键
- 动态代码执行: 许多平台使用动态生成的混淆代码,需要 JS 解释器来处理
- Token 时效性: 大多数签名包含时间戳,需要实时计算而非缓存
相关内容
支付宝
微信