艾曼语 发表于 2025-10-1 18:58:36

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

@
目录

[*]1. 加密原理
[*]2. 参考代码

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

该音乐平台加密数据为如下图片这个:

所加密的数据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),最后拼接所有的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(),
      {
            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(); // 测试使用
    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,b = arr,c = arr;
      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 + str2;
      if(b === undefined){
            ans += "==";
      }else if(c === undefined){
            ans += str2 + '=';
      }else{
            ans += str2 + str2;
      }
    }
    console.log(ans)
    return ans;
}

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

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

森萌黠 发表于 4 天前

感谢发布原创作品,程序园因你更精彩

陈兰芳 发表于 4 天前

感谢发布原创作品,程序园因你更精彩

豌畔丛 发表于 前天 13:49

这个好,看起来很实用
页: [1]
查看完整版本: js逆向:某Q音乐平台请求数据模拟生成