m3u8视频文件解密QINIU-PROTECTION-10

遇到了一个网站的课想下载到本地看,发现视频的链接是m3u8格式的,直接扔到自已的下载工具里发现下载不下来,试了下N_m3u8DL也不行,那看来是m3u8本身有事了。看了下m3u8的内容,没有加密URI地址,但是EXT-X-KEY:METHOD=QINIU-PROTECTION-10,正常这里都写的是METHOD=AES-128啥的,那这个肯定是有加密,但密钥没写在m3u8文件里。

分析下请求,发现有m3u8链接,却没有从JSON信息中搜索到该链接,看了下JSON请求中,其中有一个链接的返回信息是这样:

这看起来就比较可疑了,一看就是加密字符串,啥信息还得写成这种样子,先搞一下这个看看,下断,跟踪,找到这里:

这里就是annex_path 和annex_secret的解密函数了,annex_path就是加密的m3u8链接,annex_secret就是加密的DRMKey,但这个DRMKey还不是m3u8_key,仍然是加密的还需要解密一次才是m3u8_key,先说一下如何解密annex_path 和annex_secret,上代码:

@staticmethod
    def X(e, t= "R1ZX1kLKkKQFAWWM", n=True):
        # 从json中得到的加密base64字符串,解密得到url或者是加密的key_list
        t = MD5.new(t.encode('utf-8')).hexdigest()
        # 获取前16个字符作为IV
        i = t[:16].encode('utf-8')
        # 获取后16个字符作为密钥
        r = t[16:].encode('utf-8')
        if n:
            # 解密
            cipher = AES.new(r, AES.MODE_CBC, i)
            decrypted = unpad(cipher.decrypt(base64.b64decode(e)), AES.block_size)
            return decrypted.decode('utf-8')
        else:
            # 加密
            cipher = AES.new(r, AES.MODE_CBC, i)
            encrypted = base64.b64encode(cipher.encrypt(pad(e.encode('utf-8'), AES.block_size))).decode('utf-8')
            return encrypted

annex_secret解密后会得到一个类似这样的东西:[101, 101, 101, 102, 50, 101, 50, 49, 53, 97, 52, 102, 50, 52, 53, 56],像是一个列表,解密过程不讲了,直接上代码:

def get_m3u8_key(key_str_or_list):
    # 通过一个列表 生成m3u8的 key_base64
    def hex_string_to_ascii(hexstring):
        bytes_data = bytes.fromhex(hexstring)
        ascii_str = bytes_data.decode('ascii')
        return ascii_str

    aes_key = ""
    if isinstance(key_str_or_list, str):
        key_list = key_str_or_list.split(",")
        for item in key_list:
            tmp = hex(int(item.strip()))[2:].upper()  # 10进制转16进制
            tmp = hex_string_to_ascii(tmp)
            aes_key += tmp
        return aes_key
    elif isinstance(key_str_or_list, list):
        # print(f"长度:{len(key_str_or_list)}")
        # print(f"aes_key: {aes_key}")
        for item in key_str_or_list:
            tmp = hex(int(item))[2:].upper()  # 10进制转16进制
            tmp = hex_string_to_ascii(tmp)
            aes_key += tmp
        # 得到一个16位的 bytes的aes_key,接下来转成base64
        aes_key_bytes = aes_key.encode('utf-8')
        aes_key_base64 = base64.b64encode(aes_key_bytes).decode('utf-8')

        return aes_key_base64

有了m3u8_url,有了m3u8_key,再随便操作下,就可以愉快的批量下载了。

原文链接:http://www.itawp.com/528.html,转载请注明出处。

0
没有账号? 注册  忘记密码?