今天学习下某利威是如何加密m3u8的, 在m3u8加密方面某利威算是做的不错的.
进入主题
m3u8文件, key是加密过的, Iv十六进制
因为key请求是xhr, 试着用xhr断点断下 , 分析下怎么解密的
发现在栈顶都没有完成key的解密, 只有原始的Iv , 有没有可能是在第一个ts流进行解密的, 因为它m3u8标明了是AES加密, 那肯定就有解密的过程, 自然用到的key也就是解密过后的
将第一个ts流用xhr断下, 跟踪栈
发现在栈底用到了key的请求和数据, 那继续向上找
这个b函数, 经过我调试发现, 就是key解密的地方, 但该js文件带了时间戳, 不好下断点,我用fd替换了该文件, 并在该函数开头打上debugger
断下来了, 单步步入查看解密细节
- n : 加密key的内容
- r : 取决于hls.config.minSeekHole
发现minSeekHole是变量, 全局搜索该变量, 看在哪里进行赋值, 统一打上debugger
经过笔者的漫长跟踪, 终于找到对应的位置
- vid : https://player.polyv.net/secure/(vid).json
- t.body : 就是上面vid链接请求回来的数据
大致说下代码逻辑
对vid进行md5加密 , 取前16位作为key , 后16位作为iv, 将16进制响应数据转换为bytes类型, 然后将key ,iv , body作为AES的参数传入进行解密, 解密后的结果转为字符串再通过base64解码, 最后将字符串通过json转换为对象
对象中的seed_const == 2 * minSeekHole就是我们需要的
回到key解密的环节, 因为seed_const我们拿到了, 进行接下来的解密环节
- r : 对seed_const进行md5签名
- a : r.a()对r取前16位作为解密key的AES中的key
这里有个小操作, 对固定的IV进行除2的操作,结果为
因为iv要为十六进制, 所以讲数组里的十进制数字转为十六进制, 切记最终的长度要为16
拿到了AES中的key, iv 和要解密的key内容, 最终对加密的key进行AES解密, 取前16位, 作为真正的key, 后续就可以通过解密完的key和m3u8里提供的iv对ts解密
上述所有的思维逻辑都是基于python实现, 因为特殊原因, 就不贴出代码了, 大家可以自己去操作一下, 下载ts流可以用aria2, 不懂的可以看我之前的文章
溜了, peace