由于慕课网的视频是使用ts文件流格式进行播放,但是下载后发现无法正常播放,说明进行了加密,下载其对应的m3u8文件发现是一个json报文,其m3u8文件和key文件均进行了加密处理。

1、解密m3u8

我们随便进入一个免费的慕课网课程,使用F12调出网络,然后搜索m3u8文件的下载链接

https://www.imooc.com/video/64181742255ba95a4b010436/medium.m3u8?cdn=aliyun1&ssl=1&hxk_uri=aHR0cHM6Ly93d3cuaW1vb2MuY29tL3ZpZGVvLzY0MTgxNzQyMjU1YmE5NWE0YjAxMDQzNi9tZWRpdW0uaHhrP3RpbWVzdGFtcD0xNjkwNzE2MzE0JnRva2VuPWltb29jJTNBTVdNek5HUXlPRFpsT0dFNVpEYzRNVGhoTXpaaE16TTRPR0prTkRka01XSXlNV1EyWm1Ga1pnJTNEJTNE&timestamp=1690716314&token=imooc%3ANjRhMzI3ODM4MTA1ZmU2MTJkMDFkZjFlNTBmYmUwNDM2OGQyMjgzNQ%3D%3D

我们点击相应,发现返回的是一个json报文,而不是m3u8文件的具体内容

{
    "code": 200,
    "data": {
        "info": "bVmhQqmwMVQ4G1RoHVQGZVQcYhVURCBHVClUZBdUBH9UAm5kFVQYIVQgY1Q+G1QZVAYZVGJ7VAdUfVQwfk9UZAoECgIbVB1UY1QZVDAgZC1UHVQXVBNUBmIdVBtUBVQwJmQtVBtUGVQGGVRie1QHVHtUMH5PVGQKBAoCG1QdVGNUGVQwOVQ4G1R1VBQbVAIdVHdUbBogN1QpVGQeBAdUAnNUHVQNVA9UMDFUOAp\/VFpxVAIdVHNUGVQaIElUNB1UG1QbVAYTVGIQFVR0IClUKVRkG1QYHVRyAnQVVA9UMDFUOGNUG1R9VGdUBmJ7VHlUYjFUIHlUPhtUbVQGdF49VDVUPiAXVFYfVBtUf1QGIVRiFVQ+OVQwWgVUImQEPVQCWVQdVBoiShdUX1Q4G1Q9VAZ5VGIoP1QaABFUX1Q4G1R\/VAZgAhVUeHZVVCBbVGR7VGJgY1RiFVR8LAVUVVQgZHozVAQCAnFUK1R\/VDBEA1RYG1RmfVRbVAIdVCQaHVQAOEVUG1Q9VAZ4XjFUKhogW1QYWVQ9VBtUBjNUYhVUOjoFVAFUIGQ\/VG1UBmdUYnh\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\/VDBaH1RkNgQxVAJSJ1RvVCdUMBlUOF9UG1Q\/VAY1VGdUYiIaIAtUAVRkYARkYgdUHVR\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\/VB1UD1QIQVReOB5\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\/VDBaH1RkNgQxVAJSJ1RvVCdUMBlUOF9UG1Q\/VAY1VGdUYiIaIAtUAVRkYARkYgdUHVR\/VHlUMENUOAR9VGdUYgIDVB1UL1QjVDBNVAVUOBtUMVQGYlR5VHAaVEBfVGR2BH1UAh1Ue1RuGhFUUjgIZntUYVQCHVQBVHdUKlw4Q1RWf1RmamNUYjVUZ1Q9VDB+T1RkCgQKAn9UHVQPVAhBVF44Hn9UYGJmBnlUbVREDAAYQDwEaGJ5VGYVVDggDVQIVVQbVD9UBmdUYmdUMh1UGiAPVGQrVD58P1RiJBVUIVQwG1Q4G1RTVH4xVAJZVB1UGixLVCAEWn4EamdUYhVUfnpWWVRGZHowBDdUYhVUcHtUMBVUOC1UBGBjVAJ9VAZyGiBdVENUZAIEfVQOAiwVVHdUTDAKU1RlVBtUBmACcVR7VH1UMEIIK1QCfiZiJVRDVGIhVBogNGQGBBwQDHgVVGBSQVQ4AH9UYGJ6IVQ8NVQ6FAdUOGAKBH1UQAIgFVQqAVQgA1RkfgR8JVRiMBVULVQwEAIeJj9UBAJZVC4dVBoHVCBCU1Q\/VBtUBjtUZmIVVHhQOEVUCH4EZVQCAnNUe1R7VDBBVFI4LgRrVAIDVB1UGiBQFlwBVBtUYGZlVHBiFVRhVDA5VDgbVB9UZ1QGZgNUHVR7VHVUMEVUOBtUCVRmZm4tVFJ5VHpNVFY4HjtUBiNUXBVUHVQaBDwgZEFUF1R9VBNUBmIHVAVUAi1UIGQ\/VBtUNdtl0OPRV6IA"
    },
    "msg": "OK"
}

我们点击响应下一个标签的启动器,查看m3u8链接请求完成后具体调用的js函数

我们可以从第一个函数打个断点一直往下调,发现在调用readystatechange函数时m3u8内容被解析成具体的内容了,不再是密文

t.prototype.readystatechange = function(t) {
                    var e = t.currentTarget
                      , r = e.readyState
                      , o = this.stats
                      , s = this.context
                      , a = this.config;
                    if (!o.aborted && r >= 2)
                        if (window.clearTimeout(this.requestTimeout),
                        0 === o.tfirst && (o.tfirst = Math.max(i.now(), o.trequest)),
                        4 === r) {
                            var l = e.status;
                            if (l >= 200 && l < 300) {
                                o.tload = Math.max(o.tfirst, i.now());
                                var u = void 0
                                  , c = void 0;
                                "arraybuffer" === s.responseType ? (u = e.response,
                                c = u.byteLength) : (u = e.responseText,
                                c = u.length),
                                o.loaded = o.total = c;
                                var d = {
                                    url: e.responseURL,
                                    data: u
                                };
                                this.callbacks.onSuccess(d, o, s, e)
                            } else
                                o.retry >= a.maxRetry || l >= 400 && l < 499 ? (n.logger.error(l + " while loading " + s.url),
                                this.callbacks.onError({
                                    code: l,
                                    text: e.statusText
                                }, s, e)) : (n.logger.warn(l + " while loading " + s.url + ", retrying in " + this.retryDelay + "..."),
                                this.destroy(),
                                this.retryTimeout = window.setTimeout(this.loadInternal.bind(this), this.retryDelay),
                                this.retryDelay = Math.min(2 * this.retryDelay, a.maxRetryDelay),
                                o.retry++)
                        } else
                            this.requestTimeout = window.setTimeout(this.loadtimeout.bind(this), a.timeout)
                }

具体方法为:this.callbacks.onSuccess(d, o, s, e)

而onSuccess会调用loadsuccess方法,具体代码如下:

PlaylistLoader.prototype.loadsuccess = function(response, stats, context, networkDetails) {
                        if (void 0 === networkDetails && (networkDetails = null),
                        context.isSidxRequest)
                            return this._handleSidxRequest(response, context),
                            void this._handlePlaylistLoaded(response, stats, context, networkDetails);
                        this.resetInternalLoader(context.type);
                        var mediadata = eval("(" + response.data + ")");
                        if (!mediadata.data || !mediadata.data.info)
                            return void this._handleManifestParsingError(response, context, "transcoding", networkDetails);
                        var string = destm_1.default(mediadata.data.info);
                        if (response.data = string,
                        stats.tload = performance.now(),
                        0 !== string.indexOf("#EXTM3U"))
                            return void this._handleManifestParsingError(response, context, "no EXTM3U delimiter", networkDetails);
                        if (string.indexOf("#EXTINF:") > 0 || string.indexOf("#EXT-X-TARGETDURATION:") > 0) {
                            if (!(string.indexOf("#EXTINF:") > 0 && string.indexOf("#EXT-X-KEY:") > 0))
                                return void this._handleManifestParsingError(response, context, "no EXTM3U EXTINF", networkDetails);
                            this._handleTrackOrLevelPlaylist(response, stats, context, networkDetails)
                        } else
                            this._handleMasterPlaylist(response, stats, context, networkDetails)
                    }

打断点发现在执行var string = destm_1.default(mediadata.data.info);这行代码后string的值就是明文

进入方法断点发现调用如下方法代码:

function n(t, e) {
                function r(t, e) {
                    var r = "";
                    if ("object" == typeof t)
                        for (var n = 0; n < t.length; n++)
                            r += String.fromCharCode(t[n]);
                    t = r || t;
                    for (var i, o, s = new Uint8Array(t.length), a = e.length, n = 0; n < t.length; n++)
                        o = n % a,
                        i = t[n],
                        i = i.toString().charCodeAt(0),
                        s[n] = i ^ e.charCodeAt(o);
                    return s
                }
                function n(t) {
                    var e = "";
                    if ("object" == typeof t)
                        for (var r = 0; r < t.length; r++)
                            e += String.fromCharCode(t[r]);
                    t = e || t;
                    var n = new Uint8Array(t.length);
                    for (r = 0; r < t.length; r++)
                        n[r] = t[r].toString().charCodeAt(0);
                    var i, o, r = 0;
                    for (r = 0; r < n.length; r++)
                        0 != (i = n[r] % 3) && r + i < n.length && (o = n[r + 1],
                        n[r + 1] = n[r + i],
                        n[r + i] = o,
                        r = r + i + 1);
                    return n
                }
                function i(t) {
                    var e = "";
                    if ("object" == typeof t)
                        for (var r = 0; r < t.length; r++)
                            e += String.fromCharCode(t[r]);
                    t = e || t;
                    var n = new Uint8Array(t.length);
                    for (r = 0; r < t.length; r++)
                        n[r] = t[r].toString().charCodeAt(0);
                    var r = 0
                      , i = 0
                      , o = 0
                      , s = 0;
                    for (r = 0; r < n.length; r++)
                        o = n[r] % 2,
                        o && r++,
                        s++;
                    var a = new Uint8Array(s);
                    for (r = 0; r < n.length; r++)
                        o = n[r] % 2,
                        a[i++] = o ? n[r++] : n[r];
                    return a
                }
                function o(t, e) {
                    var r = 0
                      , n = 0
                      , i = 0
                      , o = 0
                      , s = "";
                    if ("object" == typeof t)
                        for (var r = 0; r < t.length; r++)
                            s += String.fromCharCode(t[r]);
                    t = s || t;
                    var a = new Uint8Array(t.length);
                    for (r = 0; r < t.length; r++)
                        a[r] = t[r].toString().charCodeAt(0);
                    for (r = 0; r < t.length; r++)
                        if (0 != (o = a[r] % 5) && 1 != o && r + o < a.length && (i = a[r + 1],
                        n = r + 2,
                        a[r + 1] = a[r + o],
                        a[o + r] = i,
                        (r = r + o + 1) - 2 > n))
                            for (; n < r - 2; n++)
                                a[n] = a[n] ^ e.charCodeAt(n % e.length);
                    for (r = 0; r < t.length; r++)
                        a[r] = a[r] ^ e.charCodeAt(r % e.length);
                    return a
                }
                for (var s = {
                    data: {
                        info: t
                    }
                }, a = {
                    q: r,
                    h: n,
                    m: i,
                    k: o
                }, l = s.data.info, u = l.substring(l.length - 4).split(""), c = 0; c < u.length; c++)
                    u[c] = u[c].toString().charCodeAt(0) % 4;
                u.reverse();
                for (var d = [], c = 0; c < u.length; c++)
                    d.push(l.substring(u[c] + 1, u[c] + 2)),
                    l = l.substring(0, u[c] + 1) + l.substring(u[c] + 2);
                s.data.encrypt_table = d,
                s.data.key_table = [];
                for (var c in s.data.encrypt_table)
                    "q" != s.data.encrypt_table[c] && "k" != s.data.encrypt_table[c] || (s.data.key_table.push(l.substring(l.length - 12)),
                    l = l.substring(0, l.length - 12));
                s.data.key_table.reverse(),
                s.data.info = l;
                var f = new Array(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1);
                s.data.info = function(t) {
                    var e, r, n, i, o, s, a;
                    for (s = t.length,
                    o = 0,
                    a = ""; o < s; ) {
                        do {
                            e = f[255 & t.charCodeAt(o++)]
                        } while (o < s && -1 == e);
                        if (-1 == e)
                            break;
                        do {
                            r = f[255 & t.charCodeAt(o++)]
                        } while (o < s && -1 == r);
                        if (-1 == r)
                            break;
                        a += String.fromCharCode(e << 2 | (48 & r) >> 4);
                        do {
                            if (61 == (n = 255 & t.charCodeAt(o++)))
                                return a;
                            n = f[n]
                        } while (o < s && -1 == n);
                        if (-1 == n)
                            break;
                        a += String.fromCharCode((15 & r) << 4 | (60 & n) >> 2);
                        do {
                            if (61 == (i = 255 & t.charCodeAt(o++)))
                                return a;
                            i = f[i]
                        } while (o < s && -1 == i);
                        if (-1 == i)
                            break;
                        a += String.fromCharCode((3 & n) << 6 | i)
                    }
                    return a
                }(s.data.info);
                for (var c in s.data.encrypt_table) {
                    var h = s.data.encrypt_table[c];
                    if ("q" == h || "k" == h) {
                        var p = s.data.key_table.pop();
                        s.data.info = a[s.data.encrypt_table[c]](s.data.info, p)
                    } else
                        s.data.info = a[s.data.encrypt_table[c]](s.data.info)
                }
                if (e)
                    return s.data.info;//返回密钥
                var g = "";
                for (c = 0; c < s.data.info.length; c++)
                    g += String.fromCharCode(s.data.info[c]);
                return g//返回m3u8具体明文内容
            }

当解析m3u8文件时,调用这个方法,传入两个参数,第一个参数为m3u8返回的json中的info密文,第二个参数为空,当解析密钥时,调用这个方法传入两个参数,第一个参数为密钥返回的json中的info,第二个参数为1

当解析m3u8文件时返回g,解析密钥时返回s.data.info

2、解密密钥

密钥链接如下:

https://www.imooc.com/video/64181742255ba95a4b010436/medium.hxk?timestamp=1690716610&token=imooc%3AMTNiNjgxNjVmZWMxODZmNTU2MGE0YTI3MTg5OTllOWNkOWU0Y2FhNg%3D%3D

返回内容:

{
    "code": 200,
    "data": {
        "info": "Q1hmhRmUBVRUyVRUz1RU4VRU31RUmVRUJVRUHLBsBE1UVMlUVN9UVIVUVA=="
    },
    "msg": "OK"
}

3、尝试解密ts

我们通过打断点获取到上面的m3u8具体明文如下:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:5
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="https://www.imooc.com/video/64181742255ba95a4b010436/medium.hxk?timestamp=1690717513&token=imooc%3AMDZlODhiMmFmZGFlZDQwZDE1ZDIxOWFkZThjMTMwOTNlZGJkODUzMg%3D%3D"
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/976c8113be2ab9a3.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/13c7d04a9a0501ba.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/e76225934c41ab00.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/d49dd098ecededd0.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/60f78f6c87e67d79.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/7a9cd5c4f6be88b6.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/c92d1fcef734ba1a.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/b1e4d6822c049a5b.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/9acff14623491ddc.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/1c4d1000d545ac4a.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/952961ea3cc62ca6.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/9b7dd981a05b7ed0.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/9b8c9369dcd3ee6a.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/2a5a3c60d4485e1f.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/f988ee24e5515c01.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/11dd466be594f43e.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/51cd92d4e30cb9db.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/3bd268e1e82dd80a.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/2a973917f61f00fb.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/3d47022fee554a9e.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/5641c24a48ed92e8.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/576c28812811fd90.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/847459caa80fbec0.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/57204775f573b314.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/dd10d45701a40255.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/c80184d32a473ae2.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/61d441c664cbdc6d.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/7979224745e3235e.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/f6d30ed15e23c36e.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/c8bc51a505d865cd.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/67e33e5f56a3d326.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/1d60f8e3cfb2d453.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/7ba25f18bdb47268.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/5ffee6c9b3f5a42f.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/4e41b4d004b13a46.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/5bcceed650ad96e2.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/956813522670b9d2.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/4b977aa7d14929a9.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/e56ab8bfd12023b7.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/fbeba6209f3a85a9.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/5f1db4d6e0da03e4.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/1ea52df86e4bf1a4.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/6e846376d87f0685.ts
#EXTINF:5.000000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/8e98fc5642036d2d.ts
#EXTINF:1.650000,
https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/7054519648dd8429.ts
#EXT-X-ENDLIST

我们下载其中的一个ts到本地尝试解密

https://video1.sycdn.imooc.com/64181742255ba95a4b010439/M/976c8113be2ab9a3.ts

然后打断点获取十六进制密钥如下:

4305C9CFE1DF99251CB0046C4DC9DF85

创建一个m3u8文件,仅解密这一个ts文件

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:5
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="medium.key"
#EXTINF:5.000000,
976c8113be2ab9a3.ts
#EXT-X-ENDLIST

创建一个key名字为medium.key,这里使用python进行写入,也可以使用winhex等工具

hex_data = "4305C9CFE1DF99251CB0046C4DC9DF85"
binary_data = bytes.fromhex(hex_data)

file = open("medium.key", "wb")
file.write(binary_data)
file.close()

将m3u8文件、key文件、ts文件放置同一目录下

自动解密

ffmpeg -allowed_extensions ALL -i paylist.m3u8 -c copy output.mp4