摘要
本文以某度翻译网课为例,利用Chrome浏览器分析网页结构,下载视频并根据AES-128加密算法对密钥和视频解密,旨在提供一种下载加密视频的可行方法。
引言
很多同学在购买了网课之后由于害怕购买的网课到期而产生想要将视频下载下来的念头。然而,网站上的视频通常不允许直接下载,再者,就算下载下来,也会因为视频经过加密而无法播放。本文的目的就在于研究如何下载视频并解密视频。
基本知识介绍
.m3u8和.ts格式文件
.m3u8文件和.ts文件通常是同时存在的。一个大的视频文件会被分成几十上百个小片段,而这些小片段也就是所谓的.ts文件,这些.ts文件在常用播放器中均可直接播放。.m3u8文件相当于一个目录,里面记录着要播放的.ts文件的名称及其顺序。
加密与解密
(以下摘自TimeShatter的博客AES加密算法原理的详细介绍与实现-CSDN博客)
AES简介
高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的)。对称加密算法也就是加密和解密用相同的密钥,具体的加密流程如下图:
明文P:没有经过加密的数据。密钥K:用来加密明文的密码,在对称加密算法中,加密与解密的密钥是相同的。密钥为接收方与发送方协商产生,但不可以直接在网络上传输,否则会导致密钥泄漏,通常是通过非对称加密算法加密密钥,然后再通过网络传输给对方,或者直接面对面商量密钥。密钥是绝对不可以泄漏的,否则会被攻击者还原密文,窃取机密数据。AES加密函数:设AES加密函数为E,则 C = E(K, P),其中P为明文,K为密钥,C为密文。也就是说,把明文P和密钥K作为加密函数的参数输入,则加密函数E会输出密文C。密文C:经加密函数处理后的数据AES解密函数:设AES解密函数为D,则 P = D(K, C),其中C为密文,K为密钥,P为明文。也就是说,把密文C和密钥K作为解密函数的参数输入,则解密函数会输出明文P。
需要注意的是:网上的加密视频不单单只有视频经过加密处理,密钥也是经过加密处理的。
下载与解密过程
1. 下载.m3u8和.ts文件
点开要视频播放网页,右键->检查->Network,然后刷新一下网页,找到.m3u8文件和.ts文件,右键选择open in new tab下载.m3u8文件和.ts文件。
用VScode打开后发现.m3u8文件标注了加密方式:AES-128;获取密钥的链接URI;初始化向量IV
2. 获取加密过的密钥
直接访问密钥链接会显示没有token访问不了,这里就要回到网页上去找你自己的token等信息。以下方法可以直接找到加密后的密钥。
我们找到这个tokenVideoKey这一条,点击右上方的response,找到encryptedVideoKey。注意,这里的密钥是加密过的,不能直接用于解密视频。
3. 寻找密钥的密钥
寻找密钥的密钥的方法,Ziz_在其博客某网课平台m3u8 key解密算法分析以及python实现-CSDN博客有较为详细的叙述,故此处不再赘述。(补充一下,查看.js文件的话点击和Network同一行的Source栏,然后把里面每一个.js文件都点开搜索一下prototype.decrypt)
找到这一行:
这个72Fhskjglp8qjpqx就是密钥的密钥
4. 将密钥解密
然后我们把encryptedVideoKey和这个密钥的密钥拿到随便一个AES解密网站上解密就可以得到密钥。我这里用的是这个网站:AES 加密/解密 - 锤子在线工具
注意:此时我们得到的密钥是ASCII码,还要转换成16进制才行。同样也是随便找一个网站转换一下就行了。
5. 解密视频
我们有了密钥和IV(初始化向量)就可以解密视频了。这里我们参考Ziz_的博客M3U8工作原理以及key解密视频流详解_m3u8解密-CSDN博客
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
def decrypt(data,key,iv):
cipher = AES.new(key, AES.MODE_CBC, iv)
dec_data = unpad(cipher.decrypt(data), AES.block_size)
return dec_data
if __name__ == '__main__':
key = bytes.fromhex('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx') # 此处替换为你自己的密钥
iv = bytes.fromhex('5058120c7b5a6xxxxxxxxxxxxxxxxxxx') # 此处替换为你自己的初始化向量
# 读取本地加密ts文件
with open('index_854x480.m3u8.2.ts','rb') as f:
enc_ts = f.read()
# 解密ts
dec_ts = decrypt(enc_ts,key,iv)
# 将解密后的ts保存
with open('output.ts','wb') as ff:
ff.write(dec_ts)
之后输出的.ts文件就可以播放了,但是这只是一个.ts文件的解密方法,要想对多个文件进行解密的话编写一个python脚本重复执行就可以。合并.ts视频的话也是利用python脚本,结合ffmpeg就可以实现。(格式工厂不知道为啥有时会出现音画不同步的问题,但也可以尝试一下)
参考文章:
AES加密算法原理的详细介绍与实现-CSDN博客
某网课平台m3u8 key解密算法分析以及python实现-CSDN博客
M3U8工作原理以及key解密视频流详解_m3u8解密-CSDN博客