Created
September 18, 2020 01:51
-
-
Save nondanee/e55fc1c6c8590ba9fd11bde71725c1be to your computer and use it in GitHub Desktop.
cloudflare worker for weapi encrypt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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