网易云音乐获取音频链接(爬虫)破解params参数

本文详细介绍了如何通过JS逆向工程解析网易云音乐的params和encSecKey参数生成过程,涉及到AES加密、JS动态生成关键变量、使用Chrome插件reres以及Python实现加密过程。通过分析源代码,确定了加密函数和关键变量,并给出了Python AES加密的实现代码。
摘要由CSDN通过智能技术生成

网易云音乐params和encSecKey参数的生成
工具:谷歌浏览器,reres浏览器插件,python3,requests_html库
关键词:js逆向,js的AES加密,爬虫
1.首先打开网易云音乐的歌单
在这里插入图片描述
进入一个能听到音乐的页面搜索音乐文件,因为在线听歌要求加载文件速度快,体积小,所以候选音频文件有:mp3, m4a, acc。一番操作果然找到json格式的文件,找到音乐文件地址,接下来查看请求参数
在这里插入图片描述
2.经过一些列的请求发现,只有两个参数是全局的关键,params和encSecKey,搜索数值未发现携带参数的文件,疑似由js动态生成
在这里插入图片描述
3.查找生成此参数的js文件,查看此次请求的来源,找到可以文件,点击进入,再次搜索关键key
在这里插入图片描述
果然找到
在这里插入图片描述
4.分析js代码,发现关键变量是:bZ7ex(名肯定也是会变),由asrea函数生成,搜索发现这个函数就是d函数
分析变量:此函数的后3位变量肯定是不变值,都是固定的字符,关键找第一个参数如何生成
在这里插入图片描述
在这里插入图片描述

经过仔细观察params和encSecKey参数由a,b,c,d,e,这几个关键函数生成,看见for循环断点调试就很麻烦了,直接用reres插件替换成本地文件,在本地调试
在这里插入图片描述
5.被替换文件:https://s3.music.126.net/web/s/core_d889eff6d44685f138aeb17febf426d6.js(过段时间会变化)
替换文件:http://127.0.0.1/js/core_d889eff6d44685f138aeb17febf426d6.js
源代码复制粘贴到本地服务器文件
在这里插入图片描述
6.控制台输出参数,观察值,分析,d中的i由a函数生成,
在这里插入图片描述
a函数就是在b中找了16位随机字符,随机即确定,直接写死,可以正常运行,大会进行下一项
在这里插入图片描述
打印下看看是什么样
在这里插入图片描述
可以看到所有的也包括其他歌曲的encSecKey值也一样,encSecKey也为死值
在这里插入图片描述
测试发现只有这个params值可用,d函数d值为固定json格式并携带有歌曲id,也就是asrea函数的第一个参数也找到了
在这里插入图片描述
接下来找b函数,b函数一眼看出来就是AES加密(靠多年行走江湖的经验)参考这篇文章:https://blog.csdn.net/sinat_17775997/article/details/88814358
在这里插入图片描述
b函数说明

function b(a, b) {
        console.log("进入b函数 => ");
        console.log("b中a => " + a);
        console.log("b中b => " + b);
        var c = CryptoJS.enc.Utf8.parse(b);  // 十六位十六进制数作为秘钥 第一次是g(0CoJUm6Qyw8W8jud) 第二财是a循环出的i 现在写死:WCwzSK4ip8uBjv7L
            console.log("b中由b生成的c => ");
            console.log(c);
        var d = CryptoJS.enc.Utf8.parse("0102030405060708");  // 十六位十六进制数作为秘钥偏移量
            console.log("b中生成的d => ");
            console.log(d);
        var e = CryptoJS.enc.Utf8.parse(a)
            , f = CryptoJS.AES.encrypt(e, c, {    // e为密文, c为秘钥(固定值), AES加密
            iv: d,     // AES加密  iv 向量(固定值:0102030405060708)
            mode: CryptoJS.mode.CBC    //  加密模式,固定写法
        });
        // 两次加密出来f,搞定
        var bbbbbb = f.toString();
        console.log("这是b里的bbbbbb => ");
        console.log(bbbbbb);
        return bbbbbb
    }

d函数说明

function d(d, e, f, g) {
        console.log("进入d函数 =>");
        console.log("d中d =>" + d);
        console.log("d中e =>" + e);
        console.log("d中f =>" + f);
        console.log("d中g =>" + g);
        var h = {}
            , i = a(16);
        var ccc = c(i, e, f);   // 死值
        console.log("d中ccc =>" + ccc);
        return h.encText = b(d, g),   //值由  {"ids":"[1495845552]","level":"standard","encodeType":"aac","csrf_token":""}  0CoJUm6Qyw8W8jud  生成
            h.encText = b(h.encText, i),  //值由  新生成的b(d, g)  WCwzSK4ip8uBjv7L   生成
            h.encSecKey = ccc,
            h
    }

c函数就是生成encSecKey的是个死值
至此参数都ok了
加密时遇到了一个坑,aes加密填充使用的是pkcs7填充,代码参考的:https://blog.csdn.net/yt_xy/article/details/108863258
python实现代码:

from Cryptodome.Cipher import AES
import base64
import time
import json


class Encrypt:
    def __init__(self, key, iv):
        self.key = key.encode('utf-8')
        self.iv = iv.encode('utf-8')

    # @staticmethod
    def pkcs7padding(self, text):
        """明文使用PKCS7填充 """
        padding_size = len(text.encode('utf-8'))
        print("明文长度: ")
        print(padding_size)
        padding = 16 - padding_size % 16
        print(padding)
        padding_text = chr(padding) * padding
        print(chr(padding))
        return text + padding_text

    def aes_encrypt(self, content):
        """ AES加密 """
        cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
        # 处理明文
        content_padding = self.pkcs7padding(content)
        print(content_padding)
        # 加密
        encrypt_bytes = cipher.encrypt(content_padding.encode('utf-8'))
        # 重新编码
        result = str(base64.b64encode(encrypt_bytes), encoding='utf-8')
        return result

if __name__ == '__main__':
    key_one = '0CoJUm6Qyw8W8jud'
    key_two = 'WCwzSK4ip8uBjv7L'
    iv = '0102030405060708'
  # one_text = '{"ids":"[1316563155]","level":"standard","encodeType":"aac","csrf_token":""}'
    one_text = '{"ids":"[247579]","level":"standard","encodeType":"aac","csrf_token":""}'  # 固定格式的json
    one_text_e = Encrypt(key=key_one, iv=iv)
    two_text = one_text_e.aes_encrypt(one_text)
    two_text_e = Encrypt(key=key_two, iv=iv)
    two_text = two_text_e.aes_encrypt(two_text)
    print(two_text)
  • 7
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值