网易云音乐-评论客厅:逆向 encSecKey/params 评论区采集实战

做过网易云爬虫的朋友应该都清楚,网易云音乐评论接口请求时携带的encSecKeyparams双层加密堪称入门拦路虎。网上零散教程大多只贴成品加密函数,新手复制完直接一堆报错。今天全程完整拆解评论采集接口的签名逻辑,轻松跑通完整加密流程。

一、抓包分析:锁定评论接口

先随便打开一首音乐,进入评论区可以看到有很多评论,动不动就是几万页的评论。

打开浏览器抓包工具,切换一下评论页,可以看到一个comments/get的请求,这个请求就是获取这首音乐评论的数据接口。

网易云音乐-评论客厅:逆向 encSecKey/params 评论区采集实战
图1:comments/get 评论接口

如果没找到这个请求的话,随便复制一条评论搜索一下,就能看到这个接口的请求了。

点击这条请求,右侧面板切换到“载荷”(Payload),可以看到查询字符串和表单数据

网易云音乐-评论客厅:逆向 encSecKey/params 评论区采集实战
图2:请求参数中的 encSecKey 和 params

我们主要关注表单里面的encSecKeyparams这两个参数。查询字符串里面的csrf_token不需要加密,而表单里面这两个参数是需要JS逆向的,也就是我们本节课的目标。

二、全局搜索:定位加密参数

直接全局搜索encSecKey,你会搜到大量结果,其中很多都是无关的。这时可以改为搜索encSecKey:(加一个冒号),因为给请求主体赋值时,通常是在JSON对象中以key: value的形式书写,冒号是键值对的分隔符,这样能有效过滤干扰项。

网易云音乐-评论客厅:逆向 encSecKey/params 评论区采集实战
图3:全局搜索 encSecKey:

虽然加上冒号搜索减少了很多无效干扰项,但现在还是剩下很多encSecKey:这样的赋值。怎么办?一个文件一个文件都打上断点,看哪个断点触发了就去调试那个。

这边优先排在前面的core_3660..js,进入这个JS文件搜索encSecKey:,全部给打上断点。

网易云音乐-评论客厅:逆向 encSecKey/params 评论区采集实战
图4:在 core_xxx.js 中给 encSecKey 打上断点

三、断点调试:找到加密入口

该JS文件的断点打好以后,再去点击切换下一页,这次非常幸运,一发入魂,直接找到给encSecKey赋值的位置了。

网易云音乐-评论客厅:逆向 encSecKey/params 评论区采集实战
图5:断点命中,找到 encSecKey 赋值位置

你不是很奇怪我是怎么判断就是这个位置的?你可以把鼠标移到W8O变量,看看它的路径,再看看e8e.methode8e.data,这不就是请求连接、请求方式、请求主体吗?

通过代码可以知道,paramsencSecKey的值是bWo4s赋值的,而bWo4s的值又是由window.asrsea函数赋值的:

var bWo4s = window.asrsea(JSON.stringify(i8a), bod3x(["流泪", "强"]), bod3x(AY3x.md), bod3x(["爱心", "女孩", "惊恐", "大笑"]));
e8e.data = j8b.cq8i({
    params: bWo4s.encText,
    encSecKey: bWo4s.encSecKey
})

在控制台执行asrsea函数,可以发现paramsencSecKey的值就是由asrsea生成的。

网易云音乐-评论客厅:逆向 encSecKey/params 评论区采集实战
图6:控制台执行 asrsea 函数验证

在控制台中还原asrsea函数的参数,发现除了参数1是动态的值以外,其他的值都是固定的

四、算法分析:AES + 魔改RSA

继续跟进asrsea函数,看看它的整体加密结构:

function b(a, b) {
    var c = CryptoJS.enc.Utf8.parse(b)
      , d = CryptoJS.enc.Utf8.parse("0102030405060708")
      , e = CryptoJS.enc.Utf8.parse(a)
      , f = CryptoJS.AES.encrypt(e, c, {
        iv: d,
        mode: CryptoJS.mode.CBC
    });
    return f.toString()
}

function c(a, b, c) {
    var d, e;
    setMaxDigits(131);
    d = new RSAKeyPair(b, "", c);
    e = encryptedString(d, a);
    return e
}

function d(d, e, f, g) {
    var h = {};
    var i = a(16);
    h.encText = b(d, g);
    h.encText = b(h.encText, i);
    h.encSecKey = c(i, e, f);
    return h
}

代码结构清晰:

  • b函数:AES-CBC加密,IV固定为0102030405060708
  • c函数:RSA加密,使用setMaxDigits(131)RSAKeyPair
  • d函数:先AES加密一次,再用随机key做第二次AES加密,最后用RSA加密随机key

本来想用Python直接实现,但发现它的RSA加密流程进行了魔改——包含字符串反转、小端序转换、补0填充、空格分隔输出,和标准RSA完全对不上。

网易云音乐-评论客厅:逆向 encSecKey/params 评论区采集实战
图7:魔改的 RSA 加密逻辑

五、代码扣取:无环境检测直接运行

那还是别那么麻烦了,直接扣代码。既然是AES和RSA算法,把全部代码扣下来就行了。这样的代码没有环境检测不用补环境,最简单。

就从d函数所在的自执行函数开始扣,扣下来写个调用,直接运行缺少哪个函数报错,就去拷贝那个函数进来。

完整扣取代码(保存为 main.js)
window = global;

!function() {
    function a(a) {
        var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = "";
        for (d = 0; a > d; d += 1)
            e = Math.random() * b.length,
            e = Math.floor(e),
            c += b.charAt(e);
        return c
    }
    function b(a, b) {
        var c = CryptoJS.enc.Utf8.parse(b)
          , d = CryptoJS.enc.Utf8.parse("0102030405060708")
          , e = CryptoJS.enc.Utf8.parse(a)
          , f = CryptoJS.AES.encrypt(e, c, {
            iv: d,
            mode: CryptoJS.mode.CBC
        });
        return f.toString()
    }
    function c(a, b, c) {
        var d, e;
        setMaxDigits(131);
        d = new RSAKeyPair(b, "", c);
        e = encryptedString(d, a);
        return e
    }
    function d(d, e, f, g) {
        var h = {}
          , i = a(16);
        h.encText = b(d, g);
        h.encText = b(h.encText, i);
        h.encSecKey = c(i, e, f);
        return h
    }
    function e(a, b, d, e) {
        var f = {};
        return f.encText = c(a + e, b, d),
        f
    }
    window.asrsea = d,
    window.ecnonasr = e
}();

// 固定参数
var e = '010001';
var f = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7';
var g = '0CoJUm6Qyw8W8jud';

function asrsea(d) {
    return window.asrsea(d, e, f, g);
}

// 测试
var d = '{"rid":"R_SO_4_3390243136","offset":"60","total":"false","limit":"20","csrf_token":""}';
var cc = asrsea(d);
console.log("params=" + cc.encText + "&encSecKey=" + cc.encSecKey);

六、Python调用:完整流程串联

代码都扣下来以后,就可以写个Python程序调用asrsea函数生成encSecKeyparams,发送请求试试看可不可以正常获取到评论列表。

其中参数d里的3390243136歌曲ID,爬取不同的歌曲需要更换。

import json
import execjs
import requests

ctx = None


def init_js(js_file_path="main.js"):
    global ctx
    with open(js_file_path, 'r', encoding='utf-8') as f:
        js_code = f.read()
        ctx = execjs.compile(js_code)


def get_comments(item_id):
    url = f'https://业务网址/weapi/comment/resource/comments/get?csrf_token=7a1b2cc8c9c64af957a742f65dac4dfe'
    headers = {
        "accept": "*/*",
        "content-type": "application/x-www-form-urlencoded",
        "origin": "https://业务网址",
        "referer": f"https://业务网址/playlist?id={item_id}",
        "user-agent": "Mozilla/5.0"
    }
    encrypt_data = {
        "rid": f"R_SO_4_{item_id}",
        "threadId": f"R_SO_4_{item_id}",
        "pageNo": "1",
        "pageSize": "20",
        "cursor": "-1",
        "offset": "0",
        "orderType": "1",
        "csrf_token": "7a1b2cc8c9c64af957a742f65dac4dfe"
    }
    d = json.dumps(encrypt_data, separators=(',', ':'))
    result = ctx.call("asrsea", d)
    post_data = {
        'params': result['encText'],
        'encSecKey': result['encSecKey']
    }
    response = requests.post(url, headers=headers, data=post_data)
    all_data = response.json()

    all_comments = all_data.get('data', {}).get('comments', [])
    return all_comments


if __name__ == '__main__':
    init_js()
    id = '3390243136'
    comments = get_comments(id)
    print("n" + "=" * 60)
    print(f"评论列表 (共{len(comments)}条)")
    print("=" * 60)
    for i, c in enumerate(comments, 1):
        print(f"{c['user']['nickname']}t{c['content'][:20]}t {c.get('likedCount', 0)}人点赞")

    print("n" + "=" * 60)
网易云音乐-评论客厅:逆向 encSecKey/params 评论区采集实战
图8:Python成功获取评论列表

给TA打赏
共{{data.count}}人
人已打赏
技术文档

协议过豆瓣验证码:手撕collect/eks加密参数(附源码)

2026-6-24 15:09:44

技术文档

油猴脚本逆向实战:一行Hook脚本代码 精准定位加密参数入口

2026-6-24 23:13:25

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
有新私信 私信列表
搜索