当前位置: 首页 > news >正文

Python实现WYY音乐下载

一、需求背景

WYY音乐作为国内主流音乐平台,其歌曲资源丰富但下载接口存在多重加密保护。本文将通过Python结合JS逆向技术,解析其核心加密逻辑,实现免费歌曲的下载功能。

二、技术难点分析

1. 接口加密机制

通过抓包分析可知,网易云核心接口使用两次加密:

  • 第一次:获取播放列表详情(/playlist/detail)

  • 第二次:获取歌曲下载地址(/song/enhance/player/url/v1)

2. 加密特征

请求参数包含两个关键字段:

params = 'wB86VLegW2dnyHI37+LxTZf4NrKoft+s6kROF0tcWs4LCQlrgaopaFZtak6x8TGsMPoLc1yXe8JEZP7CwGr5mA4/OoKXO/zUf9UYMyVuMMYRdLoKpMkWobbeLcwthG6kKBb5nDhxJOdDmvl+JS709WnXZYMbxZfXjKPgItjMujkjJYYT7LaG53f2mEFScsJI91gLV05T4DQlNRvpC6y6uHjwHBA/3LSrytaRinF7A40='
encSecKey = '71affe85fe12f4dd47ff873aa9c436fcf23ef1c2324020e3c268cdb33a03d7cab99377a066006861c9ca9e4e390d6a68c498415c5e77afd0cb6e6f077c793316587be7609873baab8935d68f1fa22c4287dcfb5b9b72062d1e11c9059b9d637b2820d9bd1c1265d13e8c4c86414a788b3db595c1fa3931a0fba02dbb9be93222'

三、逆向工程实现

1. 加密逻辑定位

通过浏览器开发者工具分析,定位到核心加密函数位于core_b7113131e0c3d9361b7b149f7ab7939f.js?b7113131e0c3d9361b7b149f7ab7939f.js中:

然后再根据参数关键词encSecKey在对应的js文件中搜索,进而分析通过js实现的方法

将所有涉及到的js文件中的function复制带自己电脑上的js文件中

完整js代码如下 后续可以将这份代码复制在本机命名为jm.js:

var data_01 = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7'
const CryptoJS = require('crypto-js');
var maxDigits, ZERO_ARRAY, bigZero, bigOne, dpl10, lr10, hexatrigesimalToChar, hexToChar, highBitMasks, lowBitMasks, biRadixBase = 2, biRadixBits = 16, bitsPerDigit = biRadixBits, biRadix = 65536, biHalfRadix = biRadix >>> 1, biRadixSquared = biRadix * biRadix, maxDigitVal = biRadix - 1, maxInteger = 9999999999999998;
setMaxDigits(20),
dpl10 = 15,
lr10 = biFromNumber(1e15),
hexatrigesimalToChar = new Array("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"),
hexToChar = new Array("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"),
highBitMasks = new Array(0,32768,49152,57344,61440,63488,64512,65024,65280,65408,65472,65504,65520,65528,65532,65534,65535),
lowBitMasks = new Array(0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535);


function RSAKeyPair(a, b, c) {
    this.e = biFromHex(a),
    this.d = biFromHex(b),
    this.m = biFromHex(c),
    this.chunkSize = 2 * biHighIndex(this.m),
    this.radix = 16,
    this.barrett = new BarrettMu(this.m)
}
function twoDigit(a) {
    return (10 > a ? "0" : "") + String(a)
}
function encryptedString(a, b) {
    for (var f, g, h, i, j, k, l, c = new Array, d = b.length, e = 0; d > e; )
        c[e] = b.charCodeAt(e),
        e++;
    for (; 0 != c.length % a.chunkSize; )
        c[e++] = 0;
    for (f = c.length,
    g = "",
    e = 0; f > e; e += a.chunkSize) {
        for (j = new BigInt,
        h = 0,
        i = e; i < e + a.chunkSize; ++h)
            j.digits[h] = c[i++],
            j.digits[h] += c[i++] << 8;
        k = a.barrett.powMod(j, a.e),
        l = 16 == a.radix ? biToHex(k) : biToString(k, a.radix),
        g += l + " "
    }
    return g.substring(0, g.length - 1)
}
function decryptedString(a, b) {
    var e, f, g, h, c = b.split(" "), d = "";
    for (e = 0; e < c.length; ++e)
        for (h = 16 == a.radix ? biFromHex(c[e]) : biFromString(c[e], a.radix),
        g = a.barrett.powMod(h, a.d),
        f = 0; f <= biHighIndex(g); ++f)
            d += String.fromCharCode(255 & g.digits[f], g.digits[f] >> 8);
    return 0 == d.charCodeAt(d.length - 1) && (d = d.substring(0, d.length - 1)),
    d
}
function setMaxDigits(a) {
    maxDigits = a,
    ZERO_ARRAY = new Array(maxDigits);
    for (var b = 0; b < ZERO_ARRAY.length; b++)
        ZERO_ARRAY[b] = 0;
    bigZero = new BigInt,
    bigOne = new BigInt,
    bigOne.digits[0] = 1
}
function BigInt(a) {
    this.digits = "boolean" == typeof a && 1 == a ? null : ZERO_ARRAY.slice(0),
    this.isNeg = !1
}
function biFromDecimal(a) {
    for (var d, e, f, b = "-"

相关文章:

  • 机器学习快速入门教程
  • 设计模式工厂模式和单例模式结合
  • QwQ-32B 模型结构
  • 杰理科技JL703N双模蓝牙芯片—云信
  • 在node.js环境中使用web服务器http-server运行html静态文件
  • pytorch 笔记:张量索引的维度扩展规则
  • 【Linux】进程概念和进程状态
  • 单片机写的小液晶屏驱动+汉字滚屏
  • 天梯赛 L2-008 最长对称子串 (天梯赛常用string函数)
  • Stable Diffusion lora训练(一)
  • 为什么要学习人工智能(AI)?—— 未来已来,AI引领时代变革
  • 第二十八篇 数据获取与数据分析:数仓体系下的专业化分工与协同
  • IIC读写EEPROM
  • 基于springboot医疗平台系统(源码+lw+部署文档+讲解),源码可白嫖!
  • 基于物联网的便携式土壤综合参数检测仪设计
  • MySQL外键约束下的索引删除难题:从报错到完美解决的实战指南
  • 医疗数据大集结
  • deepseek本地化部署
  • MySQL主从同步面试核心20问:从原理到实战深度拆解
  • System V共享内存详解:在Linux上实现内存共享的最佳实践
  • 五一首日出沪高峰,G1503高东收费站上午车速约30公里/小时
  • 乌副总理:乌美签署矿产协议
  • 摩天大楼天津117大厦复工背后:停工近十年,未知挑战和压力仍在
  • 中央网信办部署开展“清朗·整治AI技术滥用”专项行动
  • 马克思主义理论研究教学名师系列访谈|杜玉华:马克思主义是“认识世界”和“改变世界”的思维工具
  • 中吉乌铁路重点控制性工程开工建设,包括三座隧道