Skip to content

Instantly share code, notes, and snippets.

@nondanee
Created September 18, 2020 01:51
Show Gist options
  • Save nondanee/e55fc1c6c8590ba9fd11bde71725c1be to your computer and use it in GitHub Desktop.
Save nondanee/e55fc1c6c8590ba9fd11bde71725c1be to your computer and use it in GitHub Desktop.
cloudflare worker for weapi encrypt
ArrayBuffer.prototype.toString = function (encode) {
switch (encode) {
case 'base64':
return btoa(String.fromCharCode.apply(null, new Uint8Array(this)))
default:
return Object.prototype.toString.call(this)
}
}
const Buffer = { from: string => {
const buffer = new ArrayBuffer(string.length)
const array = new Uint8Array(buffer)
Array.from(Array(string.length).keys()).forEach(index => array[index] = string.charCodeAt(index))
return buffer
} }
const iv = Buffer.from('0102030405060708')
const presetKey = Buffer.from('0CoJUm6Qyw8W8jud')
const customKey = Buffer.from('XPDvTQADC4UeVHpm')
const encSecKey = 'ac890df3613ca8fd38e9614d282482326cbeee4aa035003411bb9f82446d7e8731b8a9eaa73c34d5707e9570444b6b7e011b8da2b4f2e9ec44da6883263eec19047e75bb28599b05e863e4249a128265c8a6c75ef39b85c04e2e88773e6b42f8b46141e004649d50c03ed951948cd6029837a153af86c81c88695ec0e1ab8386'
const weapi = async (text) => {
const cryptoPresetKey = await crypto.subtle.importKey('raw', presetKey, 'AES-CBC', true, ['encrypt'])
const stage = await crypto.subtle.encrypt({ name: 'AES-CBC', iv }, cryptoPresetKey, Buffer.from(text || ''))
const cryptoCustomKey = await crypto.subtle.importKey('raw', customKey, 'AES-CBC', true, ['encrypt'])
const final = await crypto.subtle.encrypt({ name: 'AES-CBC', iv }, cryptoCustomKey, Buffer.from(stage.toString('base64')))
const params = final.toString('base64')
return new URLSearchParams({ params, encSecKey }).toString()
}
const purify = object => (Object.keys(object).forEach(key => !object[key] && delete object[key]), object)
const handleRequest = async request => {
const { headers } = request
const CORS = purify({
'Access-Control-Allow-Credentials': true,
'Access-Control-Allow-Origin': headers.get('Origin'),
'Access-Control-Allow-Methods': headers.get('Access-Control-Request-Method'),
'Access-Control-Allow-Headers': headers.get('Access-Control-Request-Headers'),
})
if (request.method === 'OPTIONS') return new Response(null, { status: 204, headers: CORS })
const path = new URL(request.url).pathname.replace(/^\/*\w*api/, '').slice(1)
// const contentType = headers.get('content-type') || ''
// const badRequest = new Response(null, { status: 400, headers: CORS })
// if (!path || !contentType.includes('application/json')) return badRequest
// let data = {}
// try { data = await request.json() } catch(_) { return badRequest }
// data.header = { os: 'pc' }
// const text = JSON.stringify(data)
const text = await request.text()
const body = await weapi(text)
let response = await fetch(`https://music.163.com/weapi/${path}`, {
method: 'POST',
body,
headers: purify({
'Cookie': headers.get('Cookie'),
'User-Agent': headers.get('User-Agent'),
// 'X-Real-IP': headers.get('CF-Connecting-IP'),
'Content-Type': 'application/x-www-form-urlencoded',
})
})
response = new Response(response.body, response)
Object.entries(CORS).forEach(([name, value]) => response.headers.set(name, value))
return response
}
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment