feat(qs): 汽水音乐平台接入——匿名搜索/试听、抖音扫码登录、解密流代理
- sdk/qs 平台模块(安卓参数指纹匿名搜索)+ sdk/apis/qs 取流: 匿名 30s 试听,登录态走签名 track_v2 + spade key AES-CTR 解密 - /login/qs/qr 抖音扫码登录(授权后 sessionid 解锁完整曲目) - /stream/qs/:id 解密流代理,/url 返回的相对地址按请求 host 补全 - 回归测试覆盖 kw 双通道(VIP 真音频/降级链)与 qs 试听;start.bat 去掉 SOURCE_ENABLED 直启
This commit is contained in:
1 parent
aa4f2eec67
commit
0f9cff2a08
26 files changed
+2172
-9
No files matched your search
@@ -0,0 +1,26 @@
|
||||
// TT 加密(设备注册请求体):gzip + SHA512 校验 + AES-128-CBC,magic 头 "tc"
|
||||
// 移植自 fanqie-assistant src/crypto/ttencrypt.ts(Node crypto 实现)
|
||||
import { createCipheriv, createHash, randomBytes } from 'node:crypto'
|
||||
import { gzipSync } from 'node:zlib'
|
||||
|
||||
// 固定盐(base64 常量,社区共知)
|
||||
const FIXED_STRING = Buffer.from(
|
||||
'TdTC5rgxYgkOUrPHpnM7pByyRiuCmrWKGWs521cXdST0m69/COjWjSanLjfBqVovHwWlGJKu8pSXMrYqOKrdWA==',
|
||||
'base64',
|
||||
)
|
||||
|
||||
const sha512 = (data: Buffer): Buffer => createHash('sha512').update(data).digest()
|
||||
|
||||
export const encryptTT = (data: Buffer): Buffer => {
|
||||
const rand = randomBytes(32)
|
||||
const hashValue = sha512(Buffer.concat([sha512(rand), FIXED_STRING]))
|
||||
const key = hashValue.subarray(0, 16)
|
||||
const iv = hashValue.subarray(16, 32)
|
||||
const compressed = gzipSync(data)
|
||||
const payload = Buffer.concat([sha512(compressed), compressed])
|
||||
const cipher = createCipheriv('aes-128-cbc', key, iv)
|
||||
const encrypted = Buffer.concat([cipher.update(payload), cipher.final()])
|
||||
return Buffer.concat([Buffer.from([116, 99, 5, 16, 0, 0]), rand, encrypted])
|
||||
}
|
||||
|
||||
export default { encryptTT }
|
||||
Reference in new issue
Block a user