From bd407cee817f2159e6ee6658a018b0b7e3a46327 Mon Sep 17 00:00:00 2001 From: 1254qwer Date: Sat, 3 Oct 2026 17:21:32 +0800 Subject: [PATCH] fix: xeapi from BSR to CSR --- module/register_xeapikey.js | 2 +- util/crypto.js | 28 ++++++++++++++++++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/module/register_xeapikey.js b/module/register_xeapikey.js index 48e0953..0602e87 100644 --- a/module/register_xeapikey.js +++ b/module/register_xeapikey.js @@ -32,7 +32,7 @@ module.exports = async (query, request) => { const res = await axios({ method: 'POST', - url: APP_CONF.apiDomain + '/api/gorilla/anti/crawler/security/key/get', + url: APP_CONF.apiDomain + '/api/bsr/sk/get', headers: { 'User-Agent': 'NeteaseMusic/9.5.61.260802021928(9005061);Dalvik/2.1.0 (Linux; U; Android 12; HBN-AL00 Build/cd737a2.0)', diff --git a/util/crypto.js b/util/crypto.js index e34699f..cc882e2 100644 --- a/util/crypto.js +++ b/util/crypto.js @@ -206,9 +206,19 @@ const xeapiMidTransform = (ciphertext) => { for (let i = 0; i < ciphertext.length; i++) { xored[i] = ciphertext[i] ^ random[i & 0x0f] } - const b64 = Buffer.from(xored.toString('base64')) - const rot = b64.length ? (random[0] & 0x0f) % b64.length : 0 - return Buffer.concat([random, b64.subarray(rot), b64.subarray(0, rot)]) + const rot = xored.length ? (random[0] & 0x0f) % xored.length : 0 + return Buffer.concat([random, xored.subarray(rot), xored.subarray(0, rot)]) +} + +const decoder = new TextDecoder('utf-8', { fatal: true }) + +const isUtf8 = (buf) => { + try { + decoder.decode(buf) + return true + } catch { + return false + } } const xeapiEncryptS = (dynamicKey, publicKeyState, os) => { @@ -251,7 +261,13 @@ const buildXeapiPlaintext = (uri, data, options = {}) => { const bodyData = { ...data } delete bodyData.e_r const body = Buffer.from(new URLSearchParams(bodyData).toString()) - fields.body = body.toString('base64') + if (body.length) { + if (mediaType === 'application/x-www-form-urlencoded' && isUtf8(body)) { + fields.content = body.toString('utf8') + } else { + fields.body = body.toString('base64') + } + } } if (fields.queryString) { @@ -274,7 +290,7 @@ const xeapi = (uri, data, options = {}) => { const dynamicKey = activeSessionKey || crypto.randomBytes(16) const plaintext = Buffer.from(buildXeapiPlaintext(uri, data, options)) - const b = aesEcbEncrypt( + const c = aesEcbEncrypt( dynamicKey, xeapiMidTransform(aesEcbEncrypt(xeapiStaticKey, plaintext)), ) @@ -287,7 +303,7 @@ const xeapi = (uri, data, options = {}) => { ) return { - B: b.toString('base64'), + C: c.toString('base64url'), S: s.toString('base64'), R: r.toString('base64'), }