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

js逆向:某Q音乐平台请求数据模拟生成

@

目录
  • 1. 加密原理
  • 2. 参考代码

内容仅供学习使用,不能用于商业活动,且不能在该网站高用户访问时频繁访问,以免对对应服务器造成影响。

1. 加密原理

该音乐平台加密数据为如下图片这个:
PixPin_2025-09-21_16-05-10
所加密的数据data和这篇文章里的数据一样,具体请看:js逆向:某音乐平台请求参数sign签名模拟生成。

加密后的数据会随着data字符串(json数据)的长度而变化,因此加密数据的长度是不固定的。另外,最好学习一下这几个涉及到加密的类或函数,如下:

crypto
TextEncoder
crypto.subtle.encrypt

具体可以参考官方文档,链接为:SubtleCrypto.importKey()方法的使用。另外,因为涉及到加密操作的函数或类需要异步操作,读者最好有一定的异步操作的基础。基本加密原理就是利用方法crypto.getRandomValues()生成一个长度为12的加密密钥数组arr12(说的称呼可能不怎么对吧,不过总之这里会和后续加密操作联系就行。)吧!这个arr12会和上述的data数据进行一系列操作,最终结果会得到一个数组arr2,得到arr2后会再和arr12进行拼接或组合操作吧,变为一个数组arr3,如果用Python代码描述就是arr3 = arr12.extend(arr2)。(这里使用的列表类型),最后把这个arr3根据其值进行一些操作得到一个下标index,通过这个index得到字符c(str1 = ''ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'',c=str1[index]),最后拼接所有的c即可(这里涉及到arr3中3个元素得到4个字符,因为data长度不固定,因此,arr3的长度也是不固定,所以可能会存在最后依次遍历时arr3中只有1个元素或2个元素,这里需要额外讨论一下)。这里是我的一个猜测,上述代码中提到的那些函数或类我其实也并不是很了解,在上述理解中arr3 =arr12.extend(arr2)这里为什么要进行这一步呢?我想因为传到后端之后,后端进行解密操作,才能直到你具体data是什么,因为arr12初始是随机生成的,不固定的,不传到到后端,后端根本无法解密。后端解密之后然后进行sign签名参数的验证,然后辨别你的sign参数是否正确。

2. 参考代码

async function getImportKey(){const arr1 = ["raw",new Uint8Array([189, 48, 95, 16, 208, 255, 116, 182, 239, 84, 218, 184, 53, 181, 225, 207]),{name: "AES-GCM",length: 128},false,["encrypt"]]const subtle_2 = crypto.subtle;const importKey_2 = subtle_2.importKey;return await importKey_2.apply(subtle_2, arr1);
}async function getArr(str1,uint8Arr12){const cryptoKey_2 = await getImportKey();// CryptoKey 类型对象const textEncoder_2 = new TextEncoder();const encode = textEncoder_2.encode;const arr2 = encode.call(textEncoder_2,str1);// Uint8Array类型的数组const subtleCrypto_2 = crypto.subtle;const encrypt_2 = subtleCrypto_2.encrypt;const obj_2 = {'name':'AES-GCM',"iv":uint8Arr12};return await encrypt_2.call(subtleCrypto_2,obj_2,cryptoKey_2,arr2);
}async function main1(str1){const uint8Array8_2 = new Uint8Array(12); // 长度为12// const uint8Arr12 = crypto.getRandomValues(uint8Array8_2);// 每次结果都不一样的,长度为12的Uint8Array类型的数组const uint8Arr12 = new Uint8Array([211, 252, 76, 150, 99, 43, 95, 77, 49, 242, 104, 169]); // 测试使用const res = await getArr(str1,uint8Arr12);// ArrayBuffer 类型的数据const normalArr = Array.from(new Uint8Array(res));const normalArr2 = Array.from(uint8Arr12);const arr = normalArr2.concat(normalArr);let ans = '';const str2 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';for(let i = 0;i < arr.length;i += 3){// 每三个元素值最后拼成4个字符let a = arr[i],b = arr[i+1],c = arr[i+2];let a1 = a << 16,b1 = b << 8,d = a1 | b1,e = d | c,f = e >> 18,g = f & 63,f1 = e >> 12,g1 = f1 & 63,f2 = e >> 6,g2 = f2 & 63,g3 = e & 63;ans += str2[g] + str2[g1];if(b === undefined){ans += "==";}else if(c === undefined){ans += str2[g2] + '=';}else{ans += str2[g2] + str2[g3];}}console.log(ans)return ans;
}const str1 = 
// console.log(main1(JSON.stringify(str1)));
console.log(main1(str1));

参考代码中str1中有一个数据涉及隐私问题,因此没有粘贴上去了,可以直接去小编这篇文章里去复制就行。js逆向:某音乐平台请求参数sign签名模拟生成。。。

http://www.zskr.cn/news/9021.html

相关文章:

  • 深入解析:【ubuntu】ubuntu中找不到串口设备问题排查
  • 软件工程第二次作业——第一次个人编程作业
  • 【树状数组】codeforce 1288 E. Messenger Simulator
  • exsi 6.7 打补丁
  • Quart
  • java设计模式-工厂模式(文件上传) - 实践
  • 深度剖析 B 站关键词排名:策略与技巧全解析 - 详解
  • 图解25:MySQL主从复制原理
  • Zero-Shot、One-Shot、Few-Shot概念
  • SPAR类比推理模型学习(与常见小目标检测方法总结) - 详解
  • 2025.9.21——1绿
  • 故障处理:ORA-04031真实案例分享
  • 02-Media-6-rtsp_server.py 使用RTSP服务器流式传输H264和H265编码视频和音频的示例程序 - 详解
  • 深入解析:敏捷开发-Scrum(下)
  • Java课前问题列表-面向对象入门2与类的识别
  • ES——(一)基本概念 - 指南
  • 意义感是完全主观的
  • Fmt库在CentOS 7的应用指南
  • 用 Lua 实现验证码识别
  • 完整教程:【RabbitMQ】-----详解RabbitMQ高级特性之消息确认机制
  • Python网络请求库requests使用详述
  • 数据结构与排序算法:从理论到场景,解锁高效数据处理的核心逻辑 - 指南
  • 内存超频最强的千元板!微星B850MPOWER主板评测
  • Docker - Create my own Ubuntu image and run it on Windows
  • NIO重构UDP收发模块
  • 题解:SP6562 PRUBALL - Esferas
  • US$34 MB ESL Emulator
  • 采用python test测试http接口
  • CF2147 Codeforces Global Round 29 (Div. 1 + Div. 2) 解题报告
  • 详细介绍:农业XR数字融合工作站,赋能农业专业实践学习